What's the 'Ruby way' to iterate over two arrays at once

后端 未结 7 430
别跟我提以往
别跟我提以往 2020-12-04 05:52

More of a syntax curiosity than a problem to solve...

I have two arrays of equal length, and want to iterate over them both at once - for example, to output both the

相关标签:
7条回答
  • 2020-12-04 06:05

    Related to the original question, for iterating over arrays of unequal length where you want the values to cycle around you can use

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

    and Ruby will give you

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

    This saves you from the nil values that you'll get from just using zip

    0 讨论(0)
  • 2020-12-04 06:09

    There is another way to iterate over two arrays at once using enumerators:

    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
    

    Enumerators are more powerful than the examples used above, because they allow infinite series, parallel iteration, among other techniques.

    0 讨论(0)
  • 2020-12-04 06:10

    Use the Array.zip method and pass it a block to iterate over the corresponding elements sequentially.

    0 讨论(0)
  • 2020-12-04 06:14

    How about compromising, and using #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] }
    
    0 讨论(0)
  • 2020-12-04 06:18

    Simply zipping the two arrays together works well if you are dealing with arrays. But what if you are dealing with never-ending enumerators, such as something like these:

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

    enum1.zip(enum2) fails because zip tries to evaluate all the elements and combine them. Instead, do this:

    enum1.lazy.zip(enum2)
    

    That one lazy saves you by making the resulting enumerator lazy-evaluate.

    0 讨论(0)
  • 2020-12-04 06:22
    >> @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]]
    
    0 讨论(0)
提交回复
热议问题