什么是“Ruby方式”一次迭代两个数组
更多的语法好奇心比解决问题…
我有两个相等长度的数组,并且希望一次迭代它们,例如,在某个索引处输出它们的值。
@budget = [ 100, 150, 25, 105 ] @actual = [ 120, 100, 50, 100 ]
我知道我可以使用each_index
和索引到数组,如下所示:
@budget.each_index do |i| puts @budget[i] puts @actual[i] end
有没有一种Ruby方法可以做得更好? 像这样的东西?
# Obviously doesn't achieve what I want it to - but is there something like this? [@budget, @actual].each do |budget, actual| puts budget puts actual end
>> @budget = [ 100, 150, 25, 105 ] => [100, 150, 25, 105] >> @actual = [ 120, 100, 50, 100 ] => [120, 100, 50, 100] >> @budget.zip @actual => [[100, 120], [150, 100], [25, 50], [105, 100]] >> @budget.zip(@actual).each do |budget, actual| ?> puts budget >> puts actual >> end 100 120 150 100 25 50 105 100 => [[100, 120], [150, 100], [25, 50], [105, 100]]
使用Array.zip
方法并传递一个块,以顺序遍历相应的元素。
还有另外一种方法来使用枚举器一次遍历两个数组:
2.1.2 :003 > enum = [1,2,4].each => #<Enumerator: [1, 2, 4]:each> 2.1.2 :004 > enum2 = [5,6,7].each => #<Enumerator: [5, 6, 7]:each> 2.1.2 :005 > loop do 2.1.2 :006 > a1,a2=enum.next,enum2.next 2.1.2 :007?> puts "array 1 #{a1} array 2 #{a2}" 2.1.2 :008?> end array 1 1 array 2 5 array 1 2 array 2 6 array 1 4 array 2 7
枚举器比上面使用的例子更强大,因为它们允许无限序列,并行迭代等技术。
除了a.zip(b).each{|x,y| }
a.zip(b).each{|x,y| }
正如别人所说的,你也可以说[a,b].transpose.each{|x,y| }
[a,b].transpose.each{|x,y| }
,这让我感觉更加对称。 可能不会那么快,因为你正在创build额外的[a,b]
数组。
与原始问题相关,对于要循环使用的值的不等长数组进行迭代,可以使用
[1,2,3,4,5,6].zip([7,8,9].cycle)
Ruby会给你的
[[1, 7], [2, 8], [3, 9], [4, 7], [5, 8], [6, 9]]
这可以节省你从使用zip得到的nil
值
如果你正在处理数组,那么简单地将两个数组压缩在一起就行得通。 但是,如果你处理的是永无止境的统计员,比如像这样的事情:
enum1 = (1..5).cycle enum2 = (10..12).cycle
enum1.zip(enum2)
失败,因为zip
尝试评估所有元素并合并它们。 相反,这样做:
enum1.lazy.zip(enum2)
这个lazy
通过使得到的枚举器懒惰评估而节省了你。
如何妥协,并使用#each_with_index?
include Enumerable @budget = [ 100, 150, 25, 105 ] @actual = [ 120, 100, 50, 100 ] @budget.each_with_index { |val, i| puts val; puts @actual[i] }