【Ruby on Rails全栈课程】2.6 ruby的数据结构--数组(Array)

简介: 数组是一个集合,但是不仅仅是数字的集合,可以是任何对象(String、 Integer、 Fixnum、 Hash、 Symbol 等对象)的集合。数组的索引是从0开始的有序整数,可以通过正数索引或者负数索引来寻找数组中的值,数组中的值是有顺序的。

数组是一个集合,但是不仅仅是数字的集合,可以是任何对象(String、 Integer、 Fixnum、 Hash、 Symbol 等对象)的集合。数组的索引是从0开始的有序整数,可以通过正数索引或者负数索引来寻找数组中的值,数组中的值是有顺序的。


1、创建数组的方式


(1)直接创建


irb(main):018:0> arr = ["name",36,nil,23]
=> ["name", 36, nil, 23]


(2)快速定义字符串数组%w后面跟{},注意是大括号{},不是中括号[]


irb(main):019:0> arr = %w{2018-01-02 2018-01-03 2018-01-04}
=> ["2018-01-02", "2018-01-03", "2018-01-04"]


数组的索引可以用正数或者负数表示,我做了一个图,帮助大家理解。


取值举例:


irb(main):022:0> arr = ["a","b","c","d","e"]
=> ["a", "b", "c", "d", "e"]
irb(main):023:0> arr[0]
=> "a"
irb(main):024:0> arr[-1]
=> "e"


2、类型转换


(1)数组转字符串to_s、join


实际操作中,常用join方法,join方法比较灵活,可以将每个数组元素用任意字符拼接起来,连成一个字符串。


irb(main):020:0> arr = ["name",36,nil,23]
=> ["name", 36, nil, 23]
irb(main):021:0> arr.to_s
=> "[\"name\", 36, nil, 23]"
irb(main):022:0> arr.join
=> "name3623"
irb(main):023:0> arr.join(",")
=> "name,36,,23"
irb(main):024:0> arr.join("-")
=> "name-36--23"


(2)字符串转数组split、eval

如果字符串的形式同将数组直接to_s之后的形式一样,那么可以用eval方法将字符串转换成数组


irb(main):025:0> str1 = "name-36--23"
=> "name-36--23"
irb(main):026:0> str1.split("-")
=> ["name", "36", "", "23"]
irb(main):028:0> str2 = "[\"name\", 36, nil, 23]"
=> "[\"name\", 36, nil, 23]"
irb(main):029:0> eval(str2)
=> ["name", 36, nil, 23]


3、数组操作


(1)数组并集、合集、相加、相减


a&b 取a数组和b数组中元素的并集


a|b 取a数组和b数组中元素的合集


a+b 将a数组和b数组中的元素组合


a-b 从a数组中去除与b数组相同的元素


irb(main):034:0> a= [1,2,4,5]
=> [1, 2, 4, 5]
irb(main):035:0> b = [3,2,1]
=> [3, 2, 1]
irb(main):036:0> a & b
=> [1, 2]
irb(main):037:0> a | b
=> [1, 2, 4, 5, 3]
irb(main):038:0> a + b
=> [1, 2, 4, 5, 3, 2, 1]
irb(main):039:0> a - b
=> [4, 5]


(2)数组与乘法的神奇组合


a * int 将a数组乘整数,得到int个a数组元素


a * str 将a数组乘一个字符串,和上面讲的join方法差不多,返回一个由str间隔数组元素的字符串


irb(main):040:0> a = [3,2,1]
=> [3, 2, 1]
irb(main):041:0> a * 3
=> [3, 2, 1, 3, 2, 1, 3, 2, 1]
irb(main):042:0> a * "-"
=> "3-2-1"
irb(main):043:0> a * "Hello"
=> "3Hello2Hello1"


(3)arr << obj 将obj元素添加到数组中

与方法+的区别:


1)+只适应于两个数组相加,不适应于数组加字符串。两个数组相加返回一个一层数组,不会改变原先的数组


2)<<后面可以接多种类型,实际应用中,多用于接字符串,两个数组相加会返回一个二级数组,会改变原先数组的元素


irb(main):001:0> a= [1,2,4,5]
=> [1, 2, 4, 5]
irb(main):002:0> b = [3,2,1]
=> [3, 2, 1]
irb(main):003:0> c = "hello"
=> "hello"
#返回一个一层数组
irb(main):004:0> a + b
=> [1, 2, 4, 5, 3, 2, 1]
#c为一个字符串,与数组用+符号连接会报错
irb(main):005:0> a + c
TypeError: no implicit conversion of String into Array
  from (irb):5
#a数组在进行+操作之后,数组中元素没有变化
irb(main):006:0> a
=> [1, 2, 4, 5]
#返回一个二层数组(即数组里面包含了数组)
irb(main):007:0> a << b
=> [1, 2, 4, 5, [3, 2, 1]]
irb(main):008:0> a << c
=> [1, 2, 4, 5, [3, 2, 1], "hello"]
#进行<<操作后,数组中的元素发生了变化
irb(main):009:0> a
=> [1, 2, 4, 5, [3, 2, 1], "hello"]


(4)== 两个数组比较,相同返回true,否则返回false。数组相同说明数组中元素个数,顺序,内容都相等


irb(main):010:0> [1,2,3] == [1,2,3]
=> true
irb(main):011:0> [1,2,3] == [1,2]
=> false
irb(main):012:0> [1,2,3] == [3,2,1]
=> false


(5)arr[index] 返回数组中index索引对应的值,如果在数组中没有index索引,则返回nil


arr[start,length] 从start索引开始,取length个值


arr[start…end]取索引为start到索引为end对应的值,包含索引为end的值


arr[start…end]取索引为start到索引为end对应的值,不包含索引为end的值


#定义一个数组
irb(main):013:0> arr = [5,6,7,8,9,10,1,2,3,4]
=> [5, 6, 7, 8, 9, 10, 1, 2, 3, 4]
irb(main):014:0> arr[0]
=> 5
#取索引为3的数,即第四个值
irb(main):015:0> arr[3]
=> 8
#从索引3开始取两个值
irb(main):017:0> arr[3,2]
=> [8, 9]
#从索引3开始取7个值
irb(main):018:0> arr[3,7]
=> [8, 9, 10, 1, 2, 3, 4]
#取索引为3到索引为7对应的值,包含索引为7的值
irb(main):020:0> arr[3..7]
=> [8, 9, 10, 1, 2]
#取索引为3到索引为7对应的值,不包含索引为7的值
irb(main):021:0> arr[3...7]
=> [8, 9, 10, 1]


(6)arr.length 返回arr数组元素个数


irb(main):023:0> a = [1,2,3,4,5]
=> [1, 2, 3, 4, 5]
irb(main):024:0> a.length
=> 5


(7)each 遍历数组


arr.each 迭代器,用来遍历数组,返回每个数组的值


arr.each_with_index 遍历数组的返回,每个数组的值以及对应的索引


irb(main):026:0> [1,2,3,4,5].each {|x| puts "此次返回的值为:" + x.to_s}
此次返回的值为:1
此次返回的值为:2
此次返回的值为:3
此次返回的值为:4
此次返回的值为:5
=> [1, 2, 3, 4, 5]
#用do...end包裹的块
irb(main):028:0> [1,2,3,4,5].each_with_index do |x,index|
irb(main):029:1*   puts "#{x}在数组中的索引是#{index}"
irb(main):030:1> end
1在数组中的索引是0
2在数组中的索引是1
3在数组中的索引是2
4在数组中的索引是3
5在数组中的索引是4
=> [1, 2, 3, 4, 5]


(8)delete 删除元素

arr.delete(obj) 根据数组的值删除数组元素。数组中有obj元素,返回该元素,数组自身会改变,数组中没有obj元素,返回nil

arr.delete_at(index) 根据数组的索引删除数组元素。数组中有index索引,返回改索引对应的值,数组自身会改变,数组中没有index索引,返回nil

irb(main):043:0> arr1 = [1,1,2,3,1,4,5]
=> [1, 1, 2, 3, 1, 4, 5]
#删除值为1的元素
irb(main):044:0> arr1.delete(1)
=> 1
#arr1数组发生了变化,值为1的元素被全部删除
irb(main):045:0> arr1
=> [2, 3, 4, 5]
#arr1数组中没有值为8的元素,返回nil
irb(main):046:0> arr1.delete(8)
=> nil
#重新定义一个数组arr2
irb(main):047:0> arr2 = [1,2,3,4,5]
=> [1, 2, 3, 4, 5]
#删除索引为2的元素
irb(main):048:0> arr2.delete_at(2)
=> 3
#arr2数组发送了变化,原先索引为2的元素以为删除,现在索引为2的元素对应的值为4
irb(main):049:0> arr2
=> [1, 2, 4, 5]
#arr2数组中没有索引为8的元素,返回nil
irb(main):050:0> arr2.delete_at(8)
=> nil


(9)arr.empty? 判断数组是否为空

irb(main):052:0> arr1 = []
=> []
irb(main):053:0> arr2 = [nil]
=> [nil]
irb(main):054:0> arr3 = [1,2,3]
=> [1, 2, 3]
irb(main):055:0> arr1.empty?
=> true
#nil也相当于一个数组元素,所有arr2数组不为空
irb(main):056:0> arr2.empty?
=> false
irb(main):057:0> arr3.empty?
=> false


(10)取数组前面或者后面的值

arr.first 取数组第一个值,即索引为0的值

arr.first(n) 取数组前n个值

arr.last 去数组最后一个值

arr.last(n) 取数组最后n个值

irb(main):061:0> arr = [1,2,3,4,5,6,7,8]
=> [1, 2, 3, 4, 5, 6, 7, 8]
irb(main):062:0> arr.first
=> 1
irb(main):063:0> arr.first(3)
=> [1, 2, 3]
irb(main):064:0> arr.last
=> 8
irb(main):065:0> arr.last(4)
=> [5, 6, 7, 8]


(11)arr.flatten flatten英文的意思是变平,就是将层数大于1层的数组,变为一层数组


irb(main):066:0> a = [1,2,3]
=> [1, 2, 3]
irb(main):067:0> b = [2,3,4]
=> [2, 3, 4]
irb(main):068:0> c = [3,4,5]
=> [3, 4, 5]
#返回一个二层数组
irb(main):069:0> d = a << b << c
=> [1, 2, 3, [2, 3, 4], [3, 4, 5]]
#数组扁平化之后的效果
irb(main):070:0> d.flatten
=> [1, 2, 3, 2, 3, 4, 3, 4, 5]


(12)arr.uniq 将arr中的重复值去掉,返回一个没有重复的数组,常与flatten一起应用

irb(main):071:0> a = [1, 2, 3, 2, 3, 4, 3, 4, 5]
=> [1, 2, 3, 2, 3, 4, 3, 4, 5]
#将数组中重复的值去掉
irb(main):072:0> a.uniq
=> [1, 2, 3, 4, 5]
#如果是二层数组,将数字扁平化之后,再将重复的值去掉
irb(main):073:0> b = [1, 2, 3, [2, 3, 4], [3, 4, 5]]
=> [1, 2, 3, [2, 3, 4], [3, 4, 5]]
irb(main):074:0> b.flatten.uniq
=> [1, 2, 3, 4, 5]


10

(13)arr.include?(obj) 数组arr是否包含obj

#定义一个数组
irb(main):076:0> arr = ["1",2,nil,3,"m"]
=> ["1", 2, nil, 3, "m"]
#需要区分字符串和数字,包含字符串"1",而不包含数字1
irb(main):077:0> arr.include?("1")
=> true
irb(main):078:0> arr.include?(1)
=> false
irb(main):079:0> arr.include?(nil)
=> true


(14)arr.insert(index,obj…) 在arr数组中在index索引的位置插入obj一个值或多个值

#快速定义字符串数组的方法,注意是{}而不是[]
irb(main):080:0> arr = %w{a b c d e}
=> ["a", "b", "c", "d", "e"]
#在索引为1的位置,插入字符"f",其他字符后移
irb(main):081:0> arr.insert(1,"f")
=> ["a", "f", "b", "c", "d", "e"]
#从索引为0的位置开始,插入三个字符"g","h","j"
irb(main):082:0> arr.insert(0,"g","h","j")
=> ["g", "h", "j", "a", "f", "b", "c", "d", "e"]


(15)删除数组的元素,并返回被删除的元素

arr.pop 删除数组的最后一个元素,并返回被删除的元素

arr.pop(n) 删除数据的最后n个元素,并将这n个元素以数组的形式返回

arr.shift 删除数组的第一个元素,并返回被删除的元素

arr.shift(n) 删除数据的前n个元素,并将这n个元素以数组的形式返回

#定义一个数组,命名为arr1
irb(main):089:0> arr1 = %w{a b c d e}
=> ["a", "b", "c", "d", "e"]
#删除数组最后一个元素,并且返回被删除的元素
irb(main):090:0> arr1.pop
=> "e"
#再删除数组最后两个元素"c", "d",这俩元素会以数组的形式返回
irb(main):091:0> arr1.pop(2)
=> ["c", "d"]
#删除操作之后,arr1数组中的元素
irb(main):092:0> arr1
=> ["a", "b"]
#定义一个数组,命名为arr2
irb(main):094:0> arr2 = %w{f g h i j}
=> ["f", "g", "h", "i", "j"]
#删除数组第一个元素,并且返回被删除的元素
irb(main):095:0> arr2.shift
=> "f"
#再删除数组前两个元素"g", "h",这俩元素会以数组的形式返回
irb(main):096:0> arr2.shift(2)
=> ["g", "h"]
#目前arr2数组中的元素
irb(main):097:0> arr2
=> ["i", "j"]


(16)reverse数组反转

arr.reverse 将数组中的值反转过来,不改变原先arr的值

arr.reverse! 会改变arr的值

irb(main):100:0> arr = [1,3,4,5,2]
=> [1, 3, 4, 5, 2]
irb(main):101:0> arr.reverse
=> [2, 5, 4, 3, 1]
#arr数组没有改变
irb(main):102:0> arr
=> [1, 3, 4, 5, 2]
irb(main):103:0> arr.reverse!
=> [2, 5, 4, 3, 1]
#arr数组的值也会被改变
irb(main):104:0> arr
=> [2, 5, 4, 3, 1]


(17)sort将数字升序排序,与reverse结合使用为降序排序


arr.sort 将arr数字升序排序(从小到大),不会改变数组本身的值


arr.sort! 会改变arr本身的值


irb(main):105:0> arr = [1,3,4,5,2]
=> [1, 3, 4, 5, 2]
irb(main):106:0> arr.sort
=> [1, 2, 3, 4, 5]
irb(main):107:0> arr.sort.reverse
=> [5, 4, 3, 2, 1]


目录
相关文章
|
19天前
|
人工智能 前端开发 JavaScript
拿下奇怪的前端报错(一):报错信息是一个看不懂的数字数组Buffer(475) [Uint8Array],让AI大模型帮忙解析
本文介绍了前端开发中遇到的奇怪报错问题,特别是当错误信息不明确时的处理方法。作者分享了自己通过还原代码、试错等方式解决问题的经验,并以一个Vue3+TypeScript项目的构建失败为例,详细解析了如何从错误信息中定位问题,最终通过解读错误信息中的ASCII码找到了具体的错误文件。文章强调了基础知识的重要性,并鼓励读者遇到类似问题时不要慌张,耐心分析。
|
20天前
|
存储 Java
Java“(array) <X> Not Initialized” (数组未初始化)错误解决
在Java中,遇到“(array) &lt;X&gt; Not Initialized”(数组未初始化)错误时,表示数组变量已被声明但尚未初始化。解决方法是在使用数组之前,通过指定数组的大小和类型来初始化数组,例如:`int[] arr = new int[5];` 或 `String[] strArr = new String[10];`。
|
1月前
|
存储 JavaScript 前端开发
JavaScript Array(数组) 对象
JavaScript Array(数组) 对象
24 3
|
1月前
|
存储 应用服务中间件 nginx
Nginx入门 -- 基本数据结构中之ngx_str_t,ngx_array_t
Nginx入门 -- 基本数据结构中之ngx_str_t,ngx_array_t
50 0
|
1月前
|
数据采集 JavaScript 前端开发
JavaScript中通过array.filter()实现数组的数据筛选、数据清洗和链式调用,JS中数组过滤器的使用详解(附实际应用代码)
JavaScript中通过array.filter()实现数组的数据筛选、数据清洗和链式调用,JS中数组过滤器的使用详解(附实际应用代码)
|
2月前
|
Go
Golang语言之数组(array)快速入门篇
这篇文章是关于Go语言中数组的详细教程,包括数组的定义、遍历、注意事项、多维数组的使用以及相关练习题。
30 5
|
3月前
|
前端开发 测试技术 API
揭秘Ruby on Rails的神秘力量:如何让你的Web应用飞起来?
【8月更文挑战第31天】Ruby on Rails(简称RoR)是一个基于Ruby语言的开源Web应用框架,自2005年发布以来,因简洁的语法、强大的功能和高效的开发效率而广受好评。RoR采用MVC架构,提高代码可读性和可维护性,拥有庞大的社区和丰富的库支持。本文通过示例代码展示其强大之处,并介绍RoR的核心概念与最佳实践,帮助开发者更高效地构建Web应用。
41 0
|
3月前
|
前端开发 API C++
在Ruby世界中寻找你的Web框架灵魂伴侣:Rails vs Sinatra
【8月更文挑战第31天】在Ruby的世界里,选择Web框架如同挑选衣物,需根据场合和需求。Rails与Sinatra是两大热门框架,前者以其“约定优于配置”理念和全面的功能成为企业级应用的首选;后者则以轻量级和灵活性著称,适用于快速原型开发和小规模应用。通过对比两者特性,如Rails的MVC架构与Sinatra的简洁API,我们可以看到它们各有所长。选择合适的框架,如同找到旅途中的最佳伙伴,让开发之路更加顺畅愉悦。这场探索之旅教会我们,没有绝对的好坏,只有最适合的选择。
33 0
|
3天前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
50 9
|
15小时前
|
存储 JavaScript 前端开发
执行上下文和执行栈
执行上下文是JavaScript运行代码时的环境,每个执行上下文都有自己的变量对象、作用域链和this值。执行栈用于管理函数调用,每当调用一个函数,就会在栈中添加一个新的执行上下文。