在迭代另一个数组时遍历数组的更好方法是什么?例如,如果我有两个如下所示的数组:
names = [ "Rover","Fido","Lassie","Calypso"] breeds = [ "Terrier","Lhasa Apso","Collie","Bulldog"]
假设阵列彼此对应 – 也就是说,Rover是一个Terrier,Fido是Lhasa Apso等等 – 我想创建一个狗类,并为每个项目创建一个新的狗对象:
class Dog attr_reader :name,:breed def initialize(name,breed) @name = name @breed = breed end end
我可以通过以下方式遍历名称和品种:
index = 0 names.each do |name| Dog.new("#{name}","#{breeds[index]}") index = index.next end
解决方法
dogs = names.zip(breeds).map { |name,breed| Dog.new(name,breed) }
Array#zip使用参数的元素交换目标数组,所以
irb> [1,2,3].zip(['a','b','c']) #=> [ [1,'a'],[2,'b'],[3,'c'] ]
您可以使用不同长度的数组(在这种情况下,目标数组确定结果数组的长度,并使用nil填充额外的条目).
irb> [1,3,4,5].zip(['a','c'],[4,nil],[5,nil] ] irb> [1,'c','d','e']) #=> [ [1,'c'] ]
您还可以将两个以上的阵列压缩在一起:
irb> [1,[:alpha,:beta,:gamma]) #=> [ [1,'a',:alpha],:beta],:gamma] ]
Array#map是一种转换数组的好方法,因为它返回一个数组,其中每个条目都是在目标数组中相应条目上运行块的结果.
irb> [1,3].map { |n| 10 - n } #=> [ 9,8,7 ]
在数组数组上使用迭代器时,如果给出一个多参数块,则数组条目将自动分解为这些参数:
irb> [ [1,'c'] ].each { |array| p array } [ 1,'a' ] [ 2,'b' ] [ 3,'c' ] #=> nil irb> [ [1,'c'] ].each do |num,char| ...> puts "number: #{num},character: #{char}" ...> end number 1,character: a number 2,character: b number 3,character: c #=> [ [1,'c'] ]
与Matt Briggs mentioned一样,#each_with_index是另一个了解的好工具.它遍历数组的元素,依次传递每个元素的块.
irb> ['a','c'].each_with_index do |char,index| ...> puts "character #{char} at index #{index}" ...> end character a at index 0 character b at index 1 character c at index 2 #=> [ 'a','c' ]
使用像#each_with_index这样的迭代器时,可以使用括号将数组元素分解为其组成部分:
irb> [ [1,'c'] ].each_with_index do |(num,char),index| ...> puts "number: #{num},character: #{char} at index #{index}" ...> end number 1,character: a at index 0 number 2,character: b at index 1 number 3,character: c at index 2 #=> [ [1,'c'] ]