什么是“Ruby方式”一次迭代两个数组

时间:2010-08-26 22:26:25

标签: ruby arrays iterator

更多的语法好奇心而不是要解决的问题...

我有两个长度相等的数组,并希望一次迭代它们 - 例如,在某个索引处输出它们的值。

@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

7 个答案:

答案 0 :(得分:258)

>> @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]]

答案 1 :(得分:21)

使用Array.zip方法并传递一个块以按顺序迭代相应的元素。

答案 2 :(得分:20)

还有另一种方法可以使用枚举器一次迭代两个数组:

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

枚举器比上面使用的示例更强大,因为它们允许无限级数,并行迭代以及其他技术。

答案 3 :(得分:16)

除了其他人所说的a.zip(b).each{|x,y| }之外,您还可以说[a,b].transpose.each{|x,y| },这让我感觉更加对称。但是,可能不会那么快,因为您正在创建额外的[a,b]数组。

答案 4 :(得分:13)

与原始问题相关,对于迭代不等长度的数组,您希望值循环可以使用

[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

答案 5 :(得分:6)

如果要处理数组,简单地将两个数组压缩在一起效果很好。但是,如果你正在处理永无止境的枚举器,例如类似的东西,那该怎么办呢?

enum1 = (1..5).cycle
enum2 = (10..12).cycle

enum1.zip(enum2)失败,因为zip尝试评估所有元素并将它们合并。相反,这样做:

enum1.lazy.zip(enum2)

一个lazy通过使得结果枚举器延迟评估来保存您。

答案 6 :(得分:2)

如何妥协,并使用#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] }