1. 数组的定义
数组是许多指向对象的引用按顺序排列的数据结构。
数组中保存的是”指向对象的引用“,而不是对象本身。
2. 数组的创建
例1
a = 1
b = "str"
#数组不一定都是同一类型
c = [a, b, 3, "abcdef"] #=> [1, "str", 3, "abcdef"]
#数组可以嵌套使用
d = [a, c, [1, 2, 3]] #=> [1,[1, "str", 3, "abcdef"], [1, 2, 3]]
3. 数组的索引
数组的各个元素按顺序被赋予了从0开始的编号,可使用这些编号和索引运算符[]对访问对象进行操作。
例2
p c[0]
p c[1]
p c[2]
p c[3]
#如果访问的索引值指向的元素不存在,则返回nil
p c[4]
p d[2]
#输出结果
#1
#"str"
#3
#"abcdef"
#nil
#[1, 2, 3]
负索引
负索引的存在,在Ruby中非常具有代表性。
Ruby中的数组对象的索引值是负数,是从末尾开始反向的编号所表示的元素。
数组的最后一个元素的编号是-1,在它前面的一个元素编号则是-2。
例3
p c[-1]
p c[-2]
#比最前面的元素还要前面,在数组范围之外
p c[-5]
#输出结果
#abcdef
#3
#nil
带有长度的索引
例4
p c[1, 2]
p c[1, 3]
p c[1, 4]
#利用负索引进行访问倒数两个索引值指向的元素
p c[-2,2]
#对范围外进行访问
p c[4,2]
#输出结果
#["str", 3]
#["str", 3, "abcdef"]
#["str", 3, "abcdef"]
#[3, "abcdef"]
#[]
表示范围的索引
..表示包含末端的范围
...表示不包含末端的范围
例5
#包含末端的范围
p c[0..1]
#不包含末端的范围
p c[0...1]
p c[-2..-1]
#负索引组合,-2表示倒数编号,3表示正数编号
p c[-2..3]
p c[-2...3]
p c[4..5]
#输出结果
[1, "str"]
[1]
[3, "abcdef"]
[3, "abcdef"]
[3]
[]
索引赋值
使用索引值可以对数组的内容进行替换。
例6
a = [1, 2]
p a
a[0] = 3
p a
#能够对超过数组长度的位置进行赋值,此时数组会被自动延长,空白索引部分用nil填充
a[4] = "4"
p a
a[0, 3] = 'a', 'b', 'c'
p a
#当指定的元素个数比原数组的元素个数多时,数组会被加长并代入
a[0, 3] = 'a', 'b', 'c', 'd'
p a
a[1..2] = 1, 2
p a
a[0, 2] = "?"
p a
a[0..2] = "A"
p a
a[-1] = "Z"
p a
#输出结果
#[1, 2]
#[3, 2]
#[3, 2, nil, nil, "4"]
#["a", "b", "c", nil, "4"]
#["a", "b", "c", "d", nil, "4"]
#["a", 1, 2, "d", nil, "4"]
#["?", 2, "d", nil, "4"]
#["A", nil, "4"]
#["A", nil, "Z"]
4. 数组的比较
例7
array1 = [1, 2, "str"]
array2 = [1, 2, "str"]
p array1 === array2 #=>true
array = ["str", 1, 2]
p array === [1, 2, "str", "extra"] #=>false
5. 数组的各种各样的方法
例8
array = ["a", "b", "c"]
#输出数组的长度
p array.length
#输出数组的元素个数(即长度)
p array.size
#array的元素copy
p array *=2
#是否包含c
p array.include? "c"
#对数组进行排序,生成新的数组,并不改变原来的array数组
p array.sort
p array
#消除重复元素,并不改变原来的array数组
p array.uniq
p array
#消除重复元素,并更新原来的array数组
array.uniq!
p array
#输出结果
#3
#3
#["a", "b", "c", "a", "b", "c"]
#true
#["a", "a", "b", "b", "c", "c"]
#["a", "b", "c", "a", "b", "c"]
#["a", "b", "c"]
#["a", "b", "c", "a", "b", "c"]
#["a", "b", "c"]
6. 带有代码块的方法和迭代
对带有代码块的方法的调用进行编程时可以用do ... end 与 花括号{}。 do ... end 和花括号{}的区别仅仅在于结合强度而已。
数组对象拥有很多带有代码块的方法,其中很多事对反复操作的抽象化,成为迭代方法。其中最具代表性的是each。
例9
array = ["a", "b", "c"]
array.each do |item|
print item + ""
end
#输出结果
#abc
7. 带有序数的反复操作
each_with_index是each的一种变体,能够同时获取数组元素和其索引值
例10
array = ["a", "b", "c"]
array.each_with_index do |item, index|
p [item, index]
end
#输出结果
#["a", 0]
#["b", 1]
#["c", 2]
映射(Map)
例11-1
acids = ["Adenin", "Thymine", "Guanine", "Cytosine"]
sign = acids.map{|acid| acid[0, 1]}
p sign
#输出结果
["A", "T", "G", "C"]
例11-2
acids = ["Adenin", "Thymine", "Guanine", "Cytosine"]
#对acids内的元素分别进行小写转为大写,a为临时变量
sign = acids.map{|a| a.upcase}
p sign
#输出结果
#["ADENIN", "THYMINE", "GUANINE", "CYTOSINE"]
8. 排序
例12
array = ["73", "2", "5", "1999", "53"]
#按照默认的字符串排序
p array.sort
#转化为数值后排序
p array.sort{|x,y| x.to_i <=> y.to_i}
#输出结果
#["1999", "2", "5", "53", "73"]
#["2", "5", "53", "73", "1999"]
9. 选择
将代码块中的返回值为真的元素取出,组成新的数组并返回
例:students.select{|person| person.grade == 3}