array.map! { |i| i.is_a?(Integer) ? (i + number) : i }
The .map! is a method for an Array type in Ruby. It says to map each element of the array per the given block argument. A block argument in Ruby accepts its own arguments (delimited with |...|) so you can pass in the value of the array element in question. In this case, |i| is giving a block variable, i, representing the value of the current element of array being evaluated.
The result will be an array that has the same number of elements, but each element will be the result of this mapping from each corresponding element in the original array, array. The explanation point (!) means to replace the array elements with the results rather than return a new array with the result. You could also do, array.map {... which would yield the same results, but not alter array; the results would be a new array.
The block is delimited by {} and can be expressed with do and end on separate lines:
array.map! do |i|
i.is_a?(Integer) ? (i + number) : i
end
There is no difference in behavior between using {} and do-end.
?: is the ternary if-then-else, just like in C. So exp1 ? exp2 : exp3 says, if exp1 is truthy, then do exp2 otherwise do exp3. The above, then, is equivalent to:
array.map! do |i|
if i.is_a?(Integer) then
i + number
else
i
end
end
In either case, the value of the if-then-else expression is the value of the last statement executed in the branch that was taken. That is the result, then, returned for the execution of the block for the given element, i. So the result of this entire mapping is to replace each element that is of class Integer in the array with its index plus whatever number is (hopefully, also a variable of numeric class). If the element is not an Integer, then it's replaces with just its index.