-1

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?

andy
  • 2,369
  • 2
  • 31
  • 50

4 Answers4

2

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:

Community
  • 1
  • 1
Denis de Bernardy
  • 75,850
  • 13
  • 131
  • 154
0

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'sArray` documentation]1 for more information.

Kostas Rousis
  • 5,918
  • 1
  • 33
  • 38
0

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
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Andrew Weir
  • 1,020
  • 2
  • 13
  • 27
0

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

BroiSatse
  • 44,031
  • 8
  • 61
  • 86