Andree
Andree

Reputation: 3103

How to insert an array in the middle of an array?

I have a Ruby array [1, 4]. I want to insert another array [2, 3] in the middle so that it becomes [1, 2, 3, 4]. I can achieve that with [1, 4].insert(1, [2, 3]).flatten, but is there a better way to do this?

Upvotes: 8

Views: 9863

Answers (4)

Cary Swoveland
Cary Swoveland

Reputation: 110755

One form of the method Array#[]= takes two arguments, index and length. When the latter is zero and the rvalue is an array, the method inserts the elements of the rvalue into the receiver before the element at the given index (and returns the rvalue). Therefore, to insert the elements of:

b = [2,3]

into:

a = [1,4]

before the element at index 1 (4), we write:

a[1,0] = b
  #=> [2,3]
a #=> [1,2,3,4]

Note:

a=[1,4]
a[0,0] = [2,3]
a #=> [2,3,1,4]

a=[1,4]
a[2,0] = [2,3]
a #=> [1,4,2,3]

a=[1,4]
a[4,0] = [2,3]
a #=> [1,4,nil,nil,2,3]]

which is why the insertion location is before the given index.

Upvotes: 5

Enver Dzhaparoff
Enver Dzhaparoff

Reputation: 4421

My option without array#insert method

array = [1,2,3,6,7,8]
new_array = [4,5]

array[0...array.size/2] + new_array + array[array.size/2..-1]

Upvotes: 0

sschmeck
sschmeck

Reputation: 7713

You could do it the following way.

[1,4].insert(1,*[2,3])

The insert() method handles multiple parameters. Therefore you can convert your array to parameters with the splat operator *.

Upvotes: 18

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121020

def insert_array receiver, pos, other
  receiver.insert pos, *other
end

insert_array [1, 4], 1, [2, 3]
#⇒ [1, 2, 3, 4]

or, the above might be achieved by monkeypatching the Array class:

class Array
  def insert_array pos, other
    insert pos, *other
  end
end

I believe, this is short enough notation to have any additional syntax sugar. BTW, flattening the result is not a good idea, since it will corrupt an input arrays, already having arrays inside:

[1, [4,5]].insert 1, *[2,3]
#⇒ [1, 2, 3, [4,5]]

but:

[1, [4,5]].insert(1, [2,3]).flatten
#⇒ [1, 2, 3, 4, 5]

Upvotes: 3

Related Questions