更多的语法好奇心而不是要解决的问题...
我有两个长度相等的数组,并希望一次迭代它们 - 例如,在某个索引处输出它们的值。
@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
答案 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] }