数组方法整理
方法列表:
- all()、any()、none()和one():测试数组中的所有或部分元素是否满足给定条件。条件可以是语句块中决定,也可以是参数决定
- append():等价于push()
- bsearch():二分法查找元素
- bsearch_index():二分法查找元素并返回索引位置
- count():计算数组中满足条件的元素个数,length()、size()和不带参数的count()等价
- collect()和collect!():等价于map
- combination():对数组元素进行排列操作,see also:permutation()
- compact()和compact!():移除数组中所有的nil元素
- cycle():循环迭代整个数组多次
- delete():删除数组中等于某值的元素,注意原处修改
- delete_at():删除数组中某索引位置处的元素,类似于
slice!()
,注意原处修改
- delete_if():直接从数组中删除满足语句块中条件的元素,将剩下的元素作为数组返回。注意:它是原处修改
- dig():从嵌套数组中逐层取元素
- drop():从前向后开始删除n个元素,将剩下的元素作为新数组返回,不是原处修改
- drop_while():从前向后开始删除元素,直到遇到第一个不满足语句块中条件的元素
- fetch():获取给定索引处的元素,但可定义索引越界时的处理逻辑
- fill():替换、修改给定范围的元素
- filter()和filter!():等价于select()、select!()
- first():返回数组头部的一个或多个元素
- flatten()和flatten!():按层次将嵌套数组压平
- hash:计算数组的hash值,
eql?
方法比较对象时采用的是hash值比较
- include?():判断数组中是否存在某元素
- index()和rindex():搜索数组中某元素的索引位置
- initialize_copy():使用另一数组中元素替换当前数组元素
- keep_if():直接从数组中删除不满足语句块中条件的元素,将剩下的元素作为数组返回。即保留满足条件的元素。注意:它是原处修改
- last():返回数组尾部的一个或多个元素
- length():返回数组元素个数,length()、size()和不带参数的count()等价
- map()和map!():迭代数组中每个元素并对它们每一个都执行语句块中的逻辑
- permutation():对数组元素作组合操作,see also:combination()
- pop():从数组尾部移除1或多个元素并返回移除的元素
- prepend():等价于unshift()
- product():将多个数组的各个元素进行组合
- push():向数组尾部追加1或多个元素并返回追加后的数组,等价于append()
- reject()和reject!():根据语句块中的规则筛选数组中不满足条件的元素
- repeated_combination():看示例
- repeated_permutation():看示例
- replace():等价于
initialize_copy()
- reverse()和reverse!():反转数组
- reverse_each():反向迭代数组
- rotate()和rotate!():转动数组
- select()和select!():根据语句块中的规则筛选数组中满足条件的元素,类似于Perl中的grep()
- simple():从数组中选取一个或n个随机元素
- shift():移除数组头部的一个或多个元素,并返回移除的元素
- shuffle()和shuffle!():打乱数组
- size():返回数组元素个数,length()、size()和不带参数的count()等价
- sum():将数组各元素相加,不限于数值相加
- sort()和sort!():对数组进行排序
- sort_by():按规则对数组元素排序
- take():从前向后开始返回n个元素
- take_while():从前向后开始返回元素,直到遇到第一个不满足语句块中条件的元素
- transpose():对多维数组行列转换,类似于zip()的特殊情况
- uniq()和uniq!():对数组去除重复元素
- unshift():向数组头部插入1个或多个给定元素并返回插入后的数组
- zip():合并多数组的元素
map()和map!()
迭代数组中每个元素,并对它们每一个都执行块中的逻辑,并返回新数组。
map()
不会修改原始数组对象,map!()
会修改原始对象。
map()和collect()等价,同理map!()和collect!()等价。
arr = [1, 2, 3, 4, 5]
new_arr = arr.map{|a| 2*a}
p new_arr1 # [2, 4, 6, 8, 10]
p arr # [1, 2, 3, 4, 5]
new_arr1 = arr.map!{|a| a**2}
p arr # [1, 4, 9, 16, 25]
p new_arr1 # [1, 4, 9, 16, 25]
zip()
arr.zip(arg, ...) → new_ary
arr.zip(arg, ...) {|arr| block} → nil
将0或多个arg数组和arr数组的元素一一对应地合并起来。合并时,数量以arr的元素数量为准,不足的以nil补足,多余的元素则忽略。
a = [ 4, 5, 6 ]
b = [ 7, 8, 9 ]
[1, 2, 3].zip(a, b) # [[1,4,7],[2,5,8],[3,6,9]]
[1, 2].zip(a, b) # [[1, 4, 7], [2, 5, 8]]
a.zip([1, 2], [8]) # [[4,1,8],[5,2,nil],[6,nil,nil]]
如果使用语句块的方式,那么每次合并后的子数组将传递给语句块中的变量,然后应用语句块的逻辑,但注意它返回的结果为nil。所以,zip()语句块中的block应当是那些能做实际操作的语句,而不是像一种返回值的方式返回操作后的结果,这样会丢弃结果。看下面示例:
a = [ 4, 5, 6 ]
b = [ 7, 8, 9 ]
[1, 2].zip(a, b) # [[1, 4, 7], [2, 5, 8]]
[1, 2].zip(a, b) do |x|
x.reduce(:+) # (1).不合理
end
[1, 2].zip(a, b) do |x|
p x.reduce(:+) # (2).合理
end
sum = 0
[1, 2].zip(a, b) do |x|
sum += x.reduce(:+) # (3).合理
end
p sum
首先,上面zip()两次传递到语句块中的变量分别是[1, 4, 7]
和[2, 5, 8]
。x.reduce(:+)
表示将x容器(此处为数组)中的元素全都相加。所以,第一次迭代语句块时,x.reduce(:+)
的结果是1+4+7=12,第二次迭代的结果是2+5+8=15。
但是在(1)中,它仅仅只是相加了,加了之后结果就被丢弃了,它不会作为新数组的元素返回,因为zip()使用语句块时返回的是nil,而不是新数组。
所以,在(2)中,对相加之后的结果加了一个p()动作将其输出,也就是使用了x.reduce的结果,并没有丢弃。
同理,在(3)中,将相加之后的结果加总到sum上,使得最后sum的值被保留,这