I have been playing around with arrays a bit, and found myself in trouble understanding the following code:
first_array = []
second_array = []
third_array = [] # I initialized 3 empty arrays
third_array << [1,2,3,4,5,6,7,8,9] # I loaded 1..9 into third_array[0]
puts third_array.size # => 1
first_array << third_array # 1..9 was loaded into first_array[0]
second_array += third_array # 1..9 was loaded into second_array[0]
puts first_array == third_array # false
puts second_array == third_array # true
puts first_array == second_array # false
puts first_array.size # 1
puts second_array.size # 1
puts third_array.size # 1
What happened with this?
second_array += third_array # I have no clue
Why aren't all the arrays equal to each other?
They exhibit fairly different behaviors. One creates and assigns a new Array
object, the other modifies an existing object.
+=
would be the same as second_array = second_array + third_array
. This sends the +
message to the second_array
object passing third_array
as the argument.
Per the documentation Array.+
returns a new array object built by concatenating the two arrays. This will return a new object.
Array.<<
simply push the parameter to the end of the existing array object:
second_array = []
second_array.object_id = 1234
second_array += [1,2,3,4]
second_array.object_id = 5678
second_array << 5
second_array.object_id = 5678
There is also a difference in how the parameter is added. By adding other elements, it will help see why your arrays are not equal:
second_array = [1, 2, 3]
# This will push the entire object, in this case an array
second_array << [1,2]
# => [1, 2, 3, [1,2]]
# Specifically appends the individual elements,
# not the entire array object
second_array + [4, 5]
# => [1, 2, 3, [1,2], 4, 5]
This is because Array.+
uses concatenation instead of pushing. Unlike Array.concat
which modifies the existing object, Array.+
returns a new object.
You can think of a Ruby implementation like:
class Array
def +(other_arr)
dup.concat(other_arr)
end
end
In your specific example, your objects look like this at the end:
first_array = [[[1, 2, 3, 4, 5, 6, 7, 8, 9]]] # [] << [] << (1..9).to_a
second_array = [[1, 2, 3, 4, 5, 6, 7, 8, 9]] # [] + ([] << (1..9).to_a)
third_array = [[1, 2, 3, 4, 5, 6, 7, 8, 9]] # [] << (1..9).to_a
<<
appends an item to an array
+=
adds an array to an array.
Examples:
[1,2] << 3
# returns [1,2,3]
[1,2] += [3,4]
# returns [1,2,3,4]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With