Javascript - insert an array inside another array

What is a 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 splices looks a little awful in terms of performance if the a2 array is large.

Thank.

+71
performance javascript arrays
Aug 11 2018-11-11T00:
source share
10 answers

You can use splice in combination with some apply tricks:

 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]; 

In ES2015 +, you can use the operator with the extension to make it a little nicer

 a1.splice(2, 0, ...a2); 
+144
Aug 11 2018-11-11T00:
source share

At first it was wrong. Should have used concat() instead.

 var a1 = [1,2,3,4,5], a2 = [21,22], startIndex = 0, insertionIndex = 2, result; result = a1.slice(startIndex, insertionIndex).concat(a2).concat(a1.slice(insertionIndex)); 

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

This expression uses slice(0, 2) [docs] to return the first two elements of a1 (where 0 is the starting index and 2 is the deleteCount element, although a1 does not change).

Intermediate result : [1,2]

He then uses concat(a2) [docs] to add a2 to the end [1,2] .

Intermediate result : [1,2,21,22] .

Then a1.slice(2) is called at the end of .concat() at the end of this expression, which is [1,2,21,22].concat(a1.slice(2)) .

Calling slice(2) with a positive integer argument will return all elements after the 2nd element, counting by natural numbers (as, for example, there are five elements, therefore [3,4,5] will be returned from a1 ), Another way of saying that the argument of a single integer index tells a1.slice() at what position of the array to start returning elements (index 2 is the third element).

Intermediate result : [1,2,21,22].concat([3,4,5])

Finally, the second .concat() adds [3,4,5] to the end of [1,2,21,22] .

Result : [1,2,21,22,3,4,5]

It may be tempting to modify Array.prototype , but you can simply extend the Array object using prototype inheritance and add the specified new object to your projects.

However, for those who live on the edge ...

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 ); 
+12
Aug 11 '11 at 20:45
source share

Now you can do this if using ES2015 or later:

 var a1 = [1,2,3,4,5]; var a2 = [21,22]; a1.splice(2, 0, ...a2); console.log(a1) // => [1,2,21,22,3,4,5] 

Refer to this question for documentation on the distribution operator (...) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator

+8
Dec 06 '16 at 18:24
source share

I wanted to find a way to do this with splice() and not iterate: 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 a1.splice.apply(a1, a2); // pass array as arguments parameter to splice console.log(a1); // [1, 2, 21, 22, 3, 4, 5]; 

In general 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 } 
+2
Aug 11 2018-11-11T00:
source share

The spread operator allows you to expand the expression in places where several arguments (for function calls) or several elements (for an array of literals).

 a2 = [21,22]; a1 = [1,2,...a2,3,4,5];//...a2 is use of spread operator console.log(a1); 
+2
Mar 02 '17 at 10:29 on
source share
 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); 
0
Aug 11 2018-11-21T00:
source share

Here is my version without much 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; } 
0
Apr 26 '13 at 8:22
source share

If you want to insert another array into the array without creating a new one, the easiest way is to use either push or unshift with apply

For example:

 a1 = [1,2,3,4,5]; a2 = [21,22]; // Insert a1 at beginning of a2 a2.unshift.apply(a2,a1); // Insert a1 at end of a2 a2.push.apply(a2,a1); 

This works because both push and unshift accept a variable number of arguments. Bonus, you can easily choose which end to attach the array to!

0
Sep 04 '14 at 15:49
source share

As mentioned in another thread, the answers above will not work in very large arrays (200K elements). See an alternate answer here, including using splicing and manual clicking: https://stackoverflow.com/a/464829/

 Array.prototype.spliceArray = function(index, insertedArray) { var postArray = this.splice(index); inPlacePush(this, insertedArray); inPlacePush(this, postArray); function inPlacePush(targetArray, pushedArray) { // Not using forEach for browser compatability var pushedArrayLength = pushedArray.length; for (var index = 0; index < pushedArrayLength; index++) { targetArray.push(pushedArray[index]); } } } 
0
Jan 04 '17 at 14:35
source share

There are really creative answers to this question. Here is a simple solution for those who are just starting with arrays. If desired, it can be made to work for browsers compatible with ECMAScript 3.

Know something about splicing before you begin.

Mozilla Developer Network: Array.prototype.splice ()

First, understand the two important forms of .splice() .

 let a1 = [1,2,3,4], a2 = [1,2]; 

Method 1) Delete elements x (deleteCount), starting from the desired index.

 let startIndex = 0, deleteCount = 2; a1.splice(startIndex, deleteCount); // returns [1,2], a1 would be [3,4] 

Method 2) Remove the elements after the desired starting index to the end of the array.

 a1.splice(2); // returns [3,4], a1 would be [1,2] 

Using .splice() , the goal may be to split a1 into the head and tail arrays using one of the two forms above.

Using method # 1, the return value will become the head, and a1 tail.

 let head = a1.splice(startIndex, deleteCount); // returns [1,2], a1 would be [3,4] 

Now in one fell swoop connect the head, body ( a2 ) and tail

 [].concat(head, a2, a1); 

Thus, this solution is more like the real world than any other presented so far. Isn't that what you would do with Legos? ;-) Here is a function executed using method # 2.

 /** *@param target Array The array to be split up into a head and tail. *@param body Array The array to be inserted between the head and tail. *@param startIndex Integer Where to split the target array. */ function insertArray(target, body, startIndex) { let tail = target.splice(startIndex); // target is now [1,2] and the head return [].concat(target, body, tail); } let newArray = insertArray([1, 2, 3, 4], ["a", "b"], 2); // [1, 2, "a", "b", 3, 4] 

In short:

 /** *@param target Array The array to be split up into a head and tail. *@param body Array The array to be inserted between the head and tail. *@param startIndex Integer Where to split the target array. */ function insertArray(target, body, startIndex) { return [].concat(target, body, target.splice(startIndex)); } 

safer:

 /** *@param target Array The array to be split up into a head and tail. *@param body Array The array to be inserted between the head and tail. *@param startIndex Integer Where to split the target array. *@throws Error The value for startIndex must fall between the first and last index, exclusive. */ function insertArray(target, body, startIndex) { const ARRAY_START = 0, ARRAY_END = target.length - 1, ARRAY_NEG_END = -1, START_INDEX_MAGNITUDE = Math.abs(startIndex); if (startIndex === ARRAY_START) { throw new Error("The value for startIndex cannot be zero (0)."); } if (startIndex === ARRAY_END || startIndex === ARRAY_NEG_END) { throw new Error("The startIndex cannot be equal to the last index in target, or -1."); } if (START_INDEX_MAGNITUDE >= ARRAY_END) { throw new Error("The absolute value of startIndex must be less than the last index."); } return [].concat(target, body, target.splice(startIndex)); } 

Benefits of this solution include:

1) A simple premise dominates the solution - fill in an empty array.

2) The head, body and tail nomenclature feels natural.

3) There is no double call .slice() . No slicing at all.

4) No .apply() . Very unnecessary.

5) The chaining method is avoided.

6) Works in ECMAScript 3 and 5 just using var instead of let or const .

** 7) Ensures that the head and tail will smack over the body, unlike many other solutions presented. If you add an array before or after the borders, you should at least use .concat() !!!!

Note. Using a distribution operator ... makes it all a lot easier.

0
Apr 19 '19 at 3:47
source share



All Articles