How is array.collect! different from array.collect in Ruby?

array.collect! and array.collect both do the same thing. They are both methods used to invoke the block argument given to them on each element of an array. After the operation, a new array is returned by the block.

However, the difference is that array.collect! permanently changes the original array, but array.collect does not.

Syntax

array.collect{|item|block}
# OR
array.collect!{|item|block}

Parameter

item: This represents each element in the array.

block: What should happen to each item is specified here.

Return value

A new array is returned that contains values returned by the block.

Example

In the example below, we will demonstrate the difference between the methods array.collect and array.collect!.

# create arrays
array1 = [1, 2, 3, 4, 5]
array2 = [1, 2, 3, 4, 5]
# call array.collect on array1
# call array.collect! on array2
# array1 : add two to each element
arr1 = array1.collect{|item| item + 2}
arr2 = array2.collect!{|item| item + 2}
# print returned values to console
puts "arr1: #{arr1}"
puts "arr2: #{arr2}"
# now print the original arrays
puts "array1: #{array1}"
puts "array2: #{array2}"

Explanation

In the code above:

  • We call array.collect on array1 and call array.collect! on array2. They are both meant to increment each element of the array by two.

  • The returned arrays for array1 and array2 are stored in arr1 and arr2 respectively.

  • After this, in lines 12 and 13, we print the returned arrays to the console. The result shows that elements of the two arrays were incremented by 2.

  • The magic happens when we now print the original arrays to the console. We observe that array1 did not change, but array2 did. This is because array.collect! permanently modifies the array that calls it but array.collect does not.