类 Array

数组对象是一个有序的、整数索引的对象集合,称为元素;该对象表示一个数组数据结构

一个元素可以是任何对象(甚至是另一个数组);元素可以是任何不同类型对象的混合。

使用数组的重要数据结构包括

还有一些类似数组的数据结构

数组索引

数组索引从 0 开始,与 C 或 Java 中一样。

非负索引是从第一个元素的偏移量

负索引是从数组末尾向后的偏移量

有效范围和超出范围的索引

当且仅当非负索引小于数组的大小时,它才在有效范围内。对于一个 3 元素数组

当且仅当负索引的绝对值不大于数组的大小时,它才在有效范围内。对于一个 3 元素数组

有效索引

尽管数组的有效索引始终是一个整数,但某些方法(包括在 Array 类内部和其他地方)接受一个或多个非整数参数,这些参数是可以转换为整数的对象

创建数组

您可以使用以下方式显式创建一个 Array 对象

许多 Ruby 方法(在核心库和标准库中)都提供了实例方法to_a,它将对象转换为数组。

用法示例

除了它通过Enumerable模块混入的方法外,Array类还具有用于访问、搜索和以其他方式操作数组的专有方法。

下面说明了一些更常用的方法。

访问元素

可以使用 Array#[] 方法检索数组中的元素。它可以接受单个整数参数(数字索引)、一对参数(起始和长度)或一个范围。负索引从末尾开始计数,-1 是最后一个元素。

arr = [1, 2, 3, 4, 5, 6]
arr[2]    #=> 3
arr[100]  #=> nil
arr[-3]   #=> 4
arr[2, 3] #=> [3, 4, 5]
arr[1..4] #=> [2, 3, 4, 5]
arr[1..-3] #=> [2, 3, 4]

访问特定数组元素的另一种方法是使用 at 方法

arr.at(0) #=> 1

slice 方法的工作方式与 Array#[] 完全相同。

要对数组边界之外的索引引发错误,或者在发生这种情况时提供默认值,您可以使用 fetch

arr = ['a', 'b', 'c', 'd', 'e', 'f']
arr.fetch(100) #=> IndexError: index 100 outside of array bounds: -6...6
arr.fetch(100, "oops") #=> "oops"

特殊方法 firstlast 将分别返回数组的第一个和最后一个元素。

arr.first #=> 1
arr.last  #=> 6

要返回数组的第一个 n 个元素,请使用 take

arr.take(3) #=> [1, 2, 3]

drop 的作用与 take 相反,它会返回删除 n 个元素后的元素

arr.drop(3) #=> [4, 5, 6]

获取有关 Array 的信息

数组始终跟踪自身的长度。要查询数组中包含的元素数量,请使用 lengthcountsize

browsers = ['Chrome', 'Firefox', 'Safari', 'Opera', 'IE']
browsers.length #=> 5
browsers.count #=> 5

要检查数组是否包含任何元素

browsers.empty? #=> false

要检查数组中是否包含特定项

browsers.include?('Konqueror') #=> false

向数组添加项

可以使用 push<< 将项添加到数组的末尾

arr = [1, 2, 3, 4]
arr.push(5) #=> [1, 2, 3, 4, 5]
arr << 6    #=> [1, 2, 3, 4, 5, 6]

unshift 会将新项添加到数组的开头。

arr.unshift(0) #=> [0, 1, 2, 3, 4, 5, 6]

使用 insert,您可以将新元素添加到数组的任何位置。

arr.insert(3, 'apple')  #=> [0, 1, 2, 'apple', 3, 4, 5, 6]

使用 insert 方法,您还可以一次插入多个值

arr.insert(3, 'orange', 'pear', 'grapefruit')
#=> [0, 1, 2, "orange", "pear", "grapefruit", "apple", 3, 4, 5, 6]

Array 中移除项

方法 pop 会移除数组中的最后一个元素并返回它

arr =  [1, 2, 3, 4, 5, 6]
arr.pop #=> 6
arr #=> [1, 2, 3, 4, 5]

要检索并同时删除第一个项,请使用 shift

arr.shift #=> 1
arr #=> [2, 3, 4, 5]

要删除特定索引处的元素

arr.delete_at(2) #=> 4
arr #=> [2, 3, 5]

要删除数组中任何位置的特定元素,请使用 delete

arr = [1, 2, 2, 3]
arr.delete(2) #=> 2
arr #=> [1,3]

如果您需要从数组中删除 nil 值,一个有用的方法是 compact

arr = ['foo', 0, nil, 'bar', 7, 'baz', nil]
arr.compact  #=> ['foo', 0, 'bar', 7, 'baz']
arr          #=> ['foo', 0, nil, 'bar', 7, 'baz', nil]
arr.compact! #=> ['foo', 0, 'bar', 7, 'baz']
arr          #=> ['foo', 0, 'bar', 7, 'baz']

另一个常见的需求是从数组中删除重复元素。

它具有非破坏性的 uniq 和破坏性的方法 uniq!

arr = [2, 5, 6, 556, 6, 6, 8, 9, 0, 123, 556]
arr.uniq #=> [2, 5, 6, 556, 8, 9, 0, 123]

遍历数组

像所有包含 Enumerable 模块的类一样,Array 都有一个 each 方法,该方法定义应该迭代哪些元素以及如何迭代。就 Array 的 each 而言,Array 实例中的所有元素都将按顺序传递给提供的块。

请注意,此操作不会更改数组。

arr = [1, 2, 3, 4, 5]
arr.each {|a| print a -= 10, " "}
# prints: -9 -8 -7 -6 -5
#=> [1, 2, 3, 4, 5]

另一个有时有用的迭代器是 reverse_each,它将按相反顺序遍历数组中的元素。

words = %w[first second third fourth fifth sixth]
str = ""
words.reverse_each {|word| str += "#{word} "}
p str #=> "sixth fifth fourth third second first "

可以使用 map 方法基于原始数组创建一个新数组,但其值由提供的块修改

arr.map {|a| 2*a}     #=> [2, 4, 6, 8, 10]
arr                   #=> [1, 2, 3, 4, 5]
arr.map! {|a| a**2}   #=> [1, 4, 9, 16, 25]
arr                   #=> [1, 4, 9, 16, 25]

Array 中选择项

可以根据块中定义的条件从数组中选择元素。选择可以以破坏性或非破坏性方式进行。虽然破坏性操作会修改它们被调用的数组,但非破坏性方法通常会返回一个包含选定元素的新数组,但保持原始数组不变。

非破坏性选择

arr = [1, 2, 3, 4, 5, 6]
arr.select {|a| a > 3}       #=> [4, 5, 6]
arr.reject {|a| a < 3}       #=> [3, 4, 5, 6]
arr.drop_while {|a| a < 4}   #=> [4, 5, 6]
arr                          #=> [1, 2, 3, 4, 5, 6]

破坏性选择

select!reject! 是与 selectreject 对应的破坏性方法

selectreject 类似,delete_ifkeep_if 在提供相同的块时具有完全相反的结果

arr.delete_if {|a| a < 4}   #=> [4, 5, 6]
arr                         #=> [4, 5, 6]

arr = [1, 2, 3, 4, 5, 6]
arr.keep_if {|a| a < 4}   #=> [1, 2, 3]
arr                       #=> [1, 2, 3]

这里有什么

首先,其他地方有什么。类 Array

这里,类 Array 提供了以下有用的方法:

创建 Array 的方法

另请参阅 创建数组

查询方法

比较方法

获取方法

这些方法不会修改 self

赋值方法

这些方法在 self 中添加、替换或重新排序元素。

删除方法

这些方法都从 self 中删除元素

组合方法

迭代方法

转换方法

其他方法