There are some truly creative answers to this question here. Here is a simple solution for those just starting out with arrays. It can be made to work all the way down to ECMAScript 3 compliant browsers, if desired.
Know something about splice before getting started.
Mozilla Developer Network: Array.prototype.splice()
First, understand two important forms of .splice()
.
let a1 = [1,2,3,4],
a2 = [1,2];
Method 1) Remove x (deleteCount) elements, starting from a desired index.
let startIndex = 0,
deleteCount = 2;
a1.splice(startIndex, deleteCount); // returns [1,2], a1 would be [3,4]
Method 2) Remove elements after a desired start index to the end of the array.
a1.splice(2); // returns [3,4], a1 would be [1,2]
Using .splice()
, a goal could be to split a1
into head and tail arrays by using one of the two forms above.
Using method #1, the return value would become the head, and a1
the tail.
let head = a1.splice(startIndex, deleteCount); // returns [1,2], a1 would be [3,4]
Now, in one fell swoop, concatenate the head, body (a2
), and tail
[].concat(head, a2, a1);
Thus, this solution is more like the real world than any other presented thus far. Is this not what you would do with Legos? ;-) Here is a function, done 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]
Shorter:
/**
*@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));
}
The advantages of this solution include:
1) A simple premise dominates the solution--fill an empty array.
2) Head, body, and tail nomenclature feels natural.
3) No double call to .slice()
. No slicing at all.
4) No .apply()
. Highly unnecessary.
5) Method chaining is avoided.
6) Works in ECMAScript 3 and 5 simply by using var
instead of let
or const
.
**7) Ensures that there will be a head and tail to slap on to the body, unlike many other solutions presented. If you are adding an array before, or after, the bounds, you should at least be using .concat()
!!!!
Note: Use of the spread opearator ...
makes all of this much easier to accomplish.