HectorOfTroy407 HectorOfTroy407 - 6 months ago 15
Ruby Question

Modify an Array in Place - Ruby

I'm wondering why the following will not modify the array in place.

I have this:

@card.map!.with_index {|value, key| key.even? ? value*=2 : value}


Which just iterates over an array, and doubles the values for all even keys.

Then I do:

@card.join.split('').map!{|x| x.to_i}


Which joins the array into one huge number, splits them into individual numbers and then maps them back to integers in an array. The only real change from step one to step two is step one would look like a=[1,2,12] and step two would look like a=[1,2,1,2]. For the second step, even though I use .map! when I p @card it appears the exact same after the first step. I have to set the second step = to something if I want to move onward with they new array. Why is this? Does the .map! in the second step not modify the array in place? Or do the linking of methods negate my ability to do that? Cheers.

Answer

tldr: A method chain only modifies objects in place, if every single method in that chain is a modify-in-place method.

The important difference in the case is the first method you call on your object. Your first example calls map! that this a methods that modifies the array in place. with_index is not important in this example, it just changes the behavior of the map!.

Your second example calls join on your array. join does not change the array in place, but it returns a totally different object: A string. Then you split the string, which creates a new array and the following map! modifies the new array in place.

So in your second example you need to assign the result to your variable again:

@card = @card.join.split('').map{ |x| x.to_i }

There might be other ways to calculate the desired result. But since you did not provide input and output examples, it is unclear what you're trying to achieve.