Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

What is the more efficient way to insert an array inside another array.

a1 = [1,2,3,4,5];
a2 = [21,22];

newArray - a1.insertAt(2,a2) -> [1,2, 21,22, 3,4,5];

Iterating a2 using splice looks a bit awfull from a performance point of view if a2 array is large.

Thanks.

share|improve this question
    
have a look at stackoverflow.com/questions/586182/… –  Endophage Aug 11 '11 at 20:45
    
it's not one item but an array, so splice is not working –  ic3 Aug 11 '11 at 20:51
add comment

5 Answers

up vote 22 down vote accepted

You can use splice combined with some apply trickery:

a1 = [1,2,3,4,5];
a2 = [21,22];

a1.splice.apply(a1, [2, 0].concat(a2));

console.log(a1); // [1, 2, 21, 22, 3, 4, 5];
share|improve this answer
    
+1 I do like how concise this is. –  user113716 Aug 11 '11 at 21:05
    
is this faster, less consuming than the solution of patrick ?. Is this version if I'm not wrong, but how can you check this? –  ic3 Aug 14 '11 at 17:24
1  
@icCube: I just ran a benchmark, comparing this method to that in patrick's answer. It starts with a1 and a2 as in the example, and injects the a2 variable into a1 10,000 times (so that in the end, you have an array with 20,005 elements). This method took: 81ms, the slice + concat method took 156ms (tested on Chrome 13). Of course, this comes with the standard caveat that in most cases, the legibility will be more important than the speed. –  nickf Aug 14 '11 at 17:37
    
Fair enough, thanks –  ic3 Aug 14 '11 at 18:23
    
@nick: In chrome if the arrays hold over 130000 items apply will throw a stackoverflow exception. jsfiddle.net/DcHCY Also happens in jsPerf I believe in FF and IE the threshhold is around 500k –  François Wahl Dec 2 '13 at 14:22
add comment

Had it wrong at first. Should have used concat() instead.

var a1 = [1,2,3,4,5];
var a2 = [21,22];

var result = a1.slice( 0, 2 ).concat( a2 ).concat( a1.slice( 2 ) );

Example: http://jsfiddle.net/f3cae/1/

This takes a slice()[docs] of a1 up to the index, then does a concat()[docs] to add a2 to that array, then uses .concat() again taking another .slice() of a1, but this time starting at the same index through the end.

And add it to Array.prototype if you wish:

Example: http://jsfiddle.net/f3cae/2/

Array.prototype.injectArray = function( idx, arr ) {
    return this.slice( 0, idx ).concat( arr ).concat( this.slice( idx ) );
};

var a1 = [1,2,3,4,5];
var a2 = [21,22];

var result = a1.injectArray( 2, a2 );

You can use the splice()[docs] method without iterating.

a1.splice( 2, 0, a2 );

http://jsfiddle.net/f3cae/

share|improve this answer
    
I get a1 with 6 items not 7 -> [1,2,[21,22],3,4,5] –  ic3 Aug 11 '11 at 20:47
    
@icCube: Yep, you're right. What was I thinking? Fixed... –  user113716 Aug 11 '11 at 20:49
    
works ! thanks a lot, let's wait some days to but this as the best answer... weird they don't have a js function for this. –  ic3 Aug 11 '11 at 21:01
    
@icCube: You're welcome. Sorry about the initial confusion. –  user113716 Aug 11 '11 at 21:05
add comment

I wanted to find a way to do this with splice() and no iterating: http://jsfiddle.net/jfriend00/W9n27/.

a1 = [1,2,3,4,5];
a2 = [21,22];

a2.unshift(2, 0);        // put first two params to splice onto front of array
Array.prototype.splice.apply(a1, a2);   // pass array as arguments parameter to splice
alert(a1.join(', '));    // [1, 2, 21, 22, 3, 4, 5];

In general purpose function form:

function arrayInsertAt(destArray, pos, arrayToInsert) {
    var args = [];
    args.push(pos);                           // where to insert
    args.push(0);                             // nothing to remove
    args = args.concat(arrayToInsert);        // add on array to insert
    destArray.splice.apply(destArray, args);  // splice it in
}
share|improve this answer
    
This modifies the a2 array as well, which is probably quite undesirable. Also, you don't need to go to the Array.prototype when you have the slice function right there on a1 or a2. –  nickf Aug 11 '11 at 21:09
    
I was aware it was modifying a2. OP can decide if that's a problem or not. Is there anything wrong with going to the prototype to get the method? It seemed more appropriate to me since I just wanted the method and the object was being added in the apply() method. –  jfriend00 Aug 11 '11 at 21:13
    
Well no, it's the exact same function, but one is shorter: Array.prototype.splice vs a1.splice :) –  nickf Aug 11 '11 at 21:39
    
Added general purpose array insertion function. –  jfriend00 Aug 11 '11 at 21:56
    
.concat returns a new array, it doesn't modify the existing one like splice. Should be args = args.concat(arrayToInsert); –  nickf Aug 11 '11 at 22:05
show 1 more comment
var a1 = [1,2,3,4,5];
var a2 = [21,22];

function injectAt(d, a1, a2) {
    for(var i=a1.length-1; i>=d; i--) {
        a1[i + a2.length] = a1[i];
    }
    for(var i=0; i<a2.length; i++) {
        a1[i+d] = a2[i];
    }
}

injectAt(2, a1, a2);

alert(a1);
share|improve this answer
add comment

Here's my version with no special tricks:

function insert_array(original_array, new_values, insert_index) {
    for (var i=0; i<new_values.length; i++) {
        original_array.splice((insert_index + i), 0, new_values[i]);
    }
    return original_array;
}
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.