0

When I run this, it correctly changes the 3 in array to "blue", but it changes all other elements to nil.

array = [1, 2, 3, 4]
array.map! do |number|
  if number == 3
    array[number] = "blue"
  end
end

Since I introduced the if statement, I expect it to leave everything else alone. Can someone explain why that's happening and how to get it to only modify the element isolated with the if statement?

sawa
  • 165,429
  • 45
  • 277
  • 381
Claire
  • 101
  • 1
  • 8

1 Answers1

2

When you run map! it:

Invokes the given block once for each element of self, replacing the element with the value returned by the block.

So when the number doesn't match 3 the block is returning nil - when it is 3 you actually don't need the assignment you're using, having simply "blue" would have the same effect.

This should accomplish what you're trying to do:

array = [1, 2, 3, 4]
array.map! do |number|
    number == 3 ? "blue" : number
end

See http://ruby-doc.org/core-2.2.0/Array.html#method-i-map-21

frostmatthew
  • 3,260
  • 4
  • 40
  • 50
  • Could you please explain that syntax in line 3? – Claire Aug 07 '15 at 22:24
  • 1
    A [ternary](https://en.wikipedia.org/wiki/%3F:#Ruby) is shorthand for an if else block (i.e. the above returns `"blue"` if `number==3` otherwise returns `number`). See also this [question](http://stackoverflow.com/questions/4252936/how-do-i-use-the-conditional-operator-in-ruby). – frostmatthew Aug 07 '15 at 22:29
  • Personally, I find `if number == 3 then 'blue' else number end` more readable. – Jörg W Mittag Aug 08 '15 at 00:58