简体   繁体   中英

Iterate over array of arrays

This has been asked before, but I can't find an answer that works. I have the following code:

[[13,14,16,11],[22,23]].each do |key,value|
  puts key
end

It should in theory print:

0
1

But instead it prints:

13
22

Why does ruby behave this way?

Why does ruby behave this way?

It's because what actually happens internally, when each and other iterators are used with a block instead of a lambda, is actually closer to this:

do |key, value, *rest|
  puts key
end

Consider this code to illustrate:

p = proc do |key,value|
  puts key
end
l = lambda do |key,value|
  puts key
end

Using the above, the following will set (key, value) to (13, 14) and (22, 23) respectively, and the above-mentioned *rest as [16, 11] in the first case (with rest getting discarded):

[[13,14,16,11],[22,23]].each(&p)

In contrast, the following will spit an argument error, because the lambda (which is similar to a block except when it comes to arity considerations) will receive the full array as an argument (without any *rest as above, since the number of arguments is strictly enforced):

[[13,14,16,11],[22,23]].each(&l) # wrong number of arguments (1 for 2)

To get the index in your case, you'll want each_with_index as highlighted in the other answers.

Related discussions:

You can get what you want with Array 's each_index' method which returns the index of the element instead of the element itself. See [Ruby's each_index' method which returns the index of the element instead of the element itself. See [Ruby's Array` documentation] 1 for more information.

You have an array of arrays - known as a two-dimensional array.

In your loop, your "value" variable is assigned to the first array, [13,14,16,11]

When you attempt to puts the "value" variable, it only returns the first element, 13.

Try changing puts value to puts value.to_s which will convert the array to a string.

If you want every value, then add another loop block to your code, to loop through each element within the "value" variable.

[[1,2,3],['a','b','c']].each do |key,value|
  value.each do |key2,value2|
    puts value2
  end
end

When you do:

[[13,14,16,11],[22,23]].each do |key,value|

before the first iteration is done it makes an assignment:

key, value = [13,14,16,11]

Such an assignment will result with key being 13 and value being 14. Instead you should use each_with_index do |array, index| . This will change the assignment to:

array, index = [[13,14,16,11], 0]

Which will result with array being [13,14,16,11] and index being 0

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM