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


127

语法上的好奇心比解决问题更重要...

我有两个相等长度的数组,并且想一次遍历两个数组,例如,以某个索引输出它们的两个值。

@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

1
两个数组大小相等吗?
阿努拉格

1
是的-已知长度相同
nfm

Answers:


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

12
“ .each”可以展开数组元素吗?我想知道还有多少不知道的Ruby:/
Nikita Rybak 2010年

5
如果要使用这样的表达式,以防万一,最好始终在方法调用中使用括号。@ budget.zip(@actual).each
AboutRuby

1
@AboutRuby:在这种情况下,这是必需的!固定。
马克-安德烈·Lafortune

2
当我看到这样的红宝石线条时,我将双手举到空中,像冠军一样在房间里走来走去!
iGbanam 2012年

9
可以缩放吗?如果我有2个10000个项目数组,这是否需要制作20,000个项目数组?该文档建议。
汤姆·安德森


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

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


1
有没有办法得到loop上面显示的索引?
Biju

16

除了a.zip(b).each{|x,y| }其他人所说的,您也可以说[a,b].transpose.each{|x,y| },这使我感到更加对称。不过,由于您正在创建额外的[a,b]数组,因此速度可能不那么快。


11
+1的好处之一transpose是,如果两个数组的长度不同,则会引发异常。
安德鲁·格林

14

与原始问题有关,用于遍历长度不等的数组,您可以在这些数组中循环使用值

[1,2,3,4,5,6].zip([7,8,9].cycle)

露比会给你

[[1, 7], [2, 8], [3, 9], [4, 7], [5, 8], [6, 9]]

nil使您免于仅使用zip即可获得的值


6

如果要处理数组,只需将两个数组压缩在一起即可。但是,如果要处理永无休止的枚举数,例如以下内容,该怎么办:

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

enum1.zip(enum2)失败,因为zip尝试评估所有元素并将其组合。相反,请执行以下操作:

enum1.lazy.zip(enum2)

那一个lazy通过使所产生的枚举懒惰评估为您节省。


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] }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.