Learning - Interesting Array Manipulation

January 3, 2013

I said in the post about my 2013 learning plans that I'd blog about whatever I learn, even if it's dead simple or something I should have known already. This is my first such post.

Let's start with this array:

a = [ 1, 3, 5, 7, 9 ]
#=> [1, 3, 5 , 7, 9]

We can replace two elements with one using the following notation:

#=>a = [1, 3, 5 , 7, 9]
a[ 2, 2 ] = 'foo'
#=>a = [1, 3, "foo", 9]

Think of a[ 2, 2 ] = "foo" as meaning, "starting at index 2, replace 2 elements with the following value". We can modify the same notation to insert a value but not replace anything in the array:

#=>a = [1, 3, "foo", 9]
a[ 2, 0 ] = 'bar'
#=>a = [1, 3, "bar", "foo", 9]

The above has the same effect as doing a.insert(2, "bar").

The range notation can also be used to replace a range of elements, like so:

#=>a = [1, 9, 8, 7, "bar", "foo", 9]
a[0..3] = []
#=>a = ["bar", "foo", 9]

Think of this as "replace elements at indexes 0 to 3 with the following". The interesting thing about both of these methods of array manipulation is that the number of new elements you're assigning doesn't have to equal the number of elements you're replacing. Using our original array, I can do the following:

#=>a = [1, 3, 5 , 7, 9]
a[ 2, 2 ] = "fizz", "buzz", "fizz", "buzz"
#=>a = [1, 3, "fizz", "buzz", "fizz", "buzz", 9]

#the above is equivalent to:
#=>a = [1, 3, 5 , 7, 9]
a[ 2, 2 ] = ["fizz", "buzz", "fizz", "buzz"]
#=>a = [1, 3, "fizz", "buzz", "fizz", "buzz", 9]

# using range notation, we can do the same as above:
#=>a = [1, 3, 5 , 7, 9]
a[2..3] = "fizz", "buzz", "fizz", "buzz"
#=>a = [1, 3, "fizz", "buzz", "fizz", "buzz", 9]

In each example I replaced two elements with four elements. The array grows automatically (see documentation on []=)

One last thing. If you specify a range outside of the size of the array, the intermin elements will be set to nil:

#=>a = ["bar", "foo", 9]
a[5..6] = "fizz", "buzz"
#=>a = ["bar", "foo", 9, nil, nil, "fizz", "buzz"]

As always in Ruby, there are multiple ways to accomplish the same thing.

See Also

Class: Array (Ruby 1.9.3)