Andrew Kim Andrew Kim - 4 months ago 7
Ruby Question

Why does ruby map enumerable return value not return expected value

I'm pretty familiar with the ruby enumerable module. Or at least so I thought. Take the following code snippet though:

names = [ "Donald", "Daisy", "Daffy" ]

new_empty_array = []

new_names_array = first_names.map do |name|
new_empty_array << name
end

puts new_names_array.inspect
# prints [["Donald", "Daisy", "Daffy"], ["Donald", "Daisy", "Daffy"], ["Donald", "Daisy", "Daffy"]]


Now, I know I'm not using map correctly here, but I was teaching a lesson on ruby enumerables and came across this example when a student was testing
map
out. The return value of the shovel(
<<
) operator is the array after an element has been added. Shouldn't the result instead be:

[["Donald"], ["Donald", "Daisy"], ["Donald", "Daisy", "Daffy"]]


It seems that the entire loop processes and the final return value of the shovel operator is processed..what gives?

Answer

The result of map, in your case, is an array which consists of references to same array new_empty_array multiple times. You are not creating 3 different arrays, but modifying same array in the body of map.

To get the output you are expecting, you need to do:

new_names_array = first_names.map do |name|
  (new_empty_array << name).dup
end

On a side note, you could use below code which is more intention-revealing than above code for the output you desire:

(1..first_names.size).map do |num|
  first_names.take(num)
end
#=> [["Donald"], ["Donald", "Daisy"], ["Donald", "Daisy", "Daffy"]]
Comments