[javascript] How to insert an item into an array at a specific index (JavaScript)?

I am looking for a JavaScript array insert method, in the style of:

arr.insert(index, item)

Preferably in jQuery, but any JavaScript implementation will do at this point.

This question is related to javascript jquery arrays

The answer is


Custom array insert methods

1. With multiple arguments and chaining support

/* Syntax:
   array.insert(index, value1, value2, ..., valueN) */

Array.prototype.insert = function(index) {
    this.splice.apply(this, [index, 0].concat(
        Array.prototype.slice.call(arguments, 1)));
    return this;
};

It can insert multiple elements (as native splice does) and supports chaining:

["a", "b", "c", "d"].insert(2, "X", "Y", "Z").slice(1, 6);
// ["b", "X", "Y", "Z", "c"]

2. With array-type arguments merging and chaining support

/* Syntax:
   array.insert(index, value1, value2, ..., valueN) */

Array.prototype.insert = function(index) {
    index = Math.min(index, this.length);
    arguments.length > 1
        && this.splice.apply(this, [index, 0].concat([].pop.call(arguments)))
        && this.insert.apply(this, arguments);
    return this;
};

It can merge arrays from the arguments with the given array and also supports chaining:

["a", "b", "c", "d"].insert(2, "V", ["W", "X", "Y"], "Z").join("-");
// "a-b-V-W-X-Y-Z-c-d"

DEMO: http://jsfiddle.net/UPphH/


i like little safety and i use this

_x000D_
_x000D_
   Array.prototype.Insert = function (item, before) {
        if (!item) return;
        if (before == null || before < 0 || before > this.length - 1) {
            this.push(item);
            return;
        }
        this.splice(before, 0,item );
    }
    
    
   var t = ["a","b"]
   
   t.Insert("v",1)
    
    console.log(t )
_x000D_
_x000D_
_x000D_


For proper functional programming and chaining purposes an invention of Array.prototype.insert() is essential. Actually splice could have been perfect if it had returned the mutated array instead of a totally meaningless empty array. So here it goes

_x000D_
_x000D_
Array.prototype.insert = function(i,...rest){_x000D_
  this.splice(i,0,...rest)_x000D_
  return this_x000D_
}_x000D_
_x000D_
var a = [3,4,8,9];_x000D_
document.write("<pre>" + JSON.stringify(a.insert(2,5,6,7)) + "</pre>");
_x000D_
_x000D_
_x000D_

Well ok the above with the Array.prototype.splice() one mutates the original array and some might complain like "you shouldn't modify what doesn't belong to you" and that might turn out to be right as well. So for the public welfare i would like to give another Array.prototype.insert() which doesn't mutate the original array. Here it goes;

_x000D_
_x000D_
Array.prototype.insert = function(i,...rest){_x000D_
  return this.slice(0,i).concat(rest,this.slice(i));_x000D_
}_x000D_
_x000D_
var a = [3,4,8,9],_x000D_
    b = a.insert(2,5,6,7);_x000D_
console.log(JSON.stringify(a));_x000D_
console.log(JSON.stringify(b));
_x000D_
_x000D_
_x000D_


If you want to insert multiple elements into an array at once check out this Stack Overflow answer: A better way to splice an array into an array in javascript

Also here are some functions to illustrate both examples:

function insertAt(array, index) {
    var arrayToInsert = Array.prototype.splice.apply(arguments, [2]);
    return insertArrayAt(array, index, arrayToInsert);
}

function insertArrayAt(array, index, arrayToInsert) {
    Array.prototype.splice.apply(array, [index, 0].concat(arrayToInsert));
    return array;
}

Finally here is a jsFiddle so you can see it for youself: http://jsfiddle.net/luisperezphd/Wc8aS/

And this is how you use the functions:

// if you want to insert specific values whether constants or variables:
insertAt(arr, 1, "x", "y", "z");

// OR if you have an array:
var arrToInsert = ["x", "y", "z"];
insertArrayAt(arr, 1, arrToInsert);

I tried this and it is working fine!

var initialArr = ["India","China","Japan","USA"];
initialArr.splice(index, 0, item);

Index is the position where you want to insert or delete the element. 0 i.e. the second parameters defines the number of element from the index to be removed item are the new entries which you want to make in array. It can be one or more than one.

initialArr.splice(2, 0, "Nigeria");
initialArr.splice(2, 0, "Australia","UK");

Another possible solution, with usage of Array#reduce.

_x000D_
_x000D_
const arr = ["apple", "orange", "raspberry"];
const arr2 = [1, 2, 4];

const insert = (arr, item, index) =>
  arr.reduce(function(s, a, i) {
    i === index ? s.push(item, a) : s.push(a);
    return s;
  }, []); 

console.log(insert(arr, "banana", 1));
console.log(insert(arr2, 3, 2))
_x000D_
_x000D_
_x000D_


Taking profit of reduce method as following:

function insert(arr, val, index) {
    return index >= arr.length 
        ? arr.concat(val)
        : arr.reduce((prev, x, i) => prev.concat(i === index ? [val, x] : x), []);
}

So at this way we can return a new array (will be a cool functional way - more much better than use push or splice) with the element inserted at index, and if the index is greater than the length of the array it will be inserted at the end.


A bit of an older thread, but I have to agree with Redu above because splice definitely has a bit of a confusing interface. And the response given by cdbajorin that "it only returns an empty array when the second parameter is 0. If it's greater than 0, it returns the items removed from the array" is, while accurate, proving the point. The function's intent is to splice or as said earlier by Jakob Keller, "to join or connect, also to change. You have an established array that you are now changing which would involve adding or removing elements...." Given that, the return value of the elements, if any, that were removed is awkward at best. And I 100% agree that this method could have been better suited to chaining if it had returned what seems natural, a new array with the spliced elements added. Then you could do things like ["19", "17"].splice(1,0,"18").join("...") or whatever you like with the returned array. The fact that it returns what was removed is just kinda nonsense IMHO. If the intention of the method was to "cut out a set of elements" and that was it's only intent, maybe. It seems like if I don't know what I'm cutting out already though, I probably have little reason to cut those elements out, doesn't it? It would be better if it behaved like concat, map, reduce, slice, etc where a new array is made from the existing array rather than mutating the existing array. Those are all chainable, and that IS a significant issue. It's rather common to chain array manipulation. Seems like the language needs to go one or the other direction and try to stick to it as much as possible. Javascript being functional and less declarative, it just seems like a strange deviation from the norm.


Here are two ways :

_x000D_
_x000D_
const array = [ 'My', 'name', 'Hamza' ];_x000D_
_x000D_
array.splice(2, 0, 'is');_x000D_
_x000D_
console.log("Method 1 : ", array.join(" "));
_x000D_
_x000D_
_x000D_

OR

_x000D_
_x000D_
Array.prototype.insert = function ( index, item ) {_x000D_
    this.splice( index, 0, item );_x000D_
};_x000D_
_x000D_
const array = [ 'My', 'name', 'Hamza' ];_x000D_
array.insert(2, 'is');_x000D_
_x000D_
console.log("Method 2 : ", array.join(" "));
_x000D_
_x000D_
_x000D_


You can implement the Array.insert method by doing this:

Array.prototype.insert = function ( index, item ) {
    this.splice( index, 0, item );
};

Then you can use it like:

var arr = [ 'A', 'B', 'D', 'E' ];
arr.insert(2, 'C');

// => arr == [ 'A', 'B', 'C', 'D', 'E' ]

Solutions & Performance

Today (2020.04.24) I perform tests for chosen solutions for big and small arrays . I tested them on MacOs High Sierra 10.13.6 on Chrome 81.0, Safari 13.1, Firefox 75.0.

Conclusions

For all browsers

  • surprisingly for small arrays non-in-place solutions based on slice and reduce (D,E,F) are usually 10x-100x faster than in-place solutions
  • for big arrays the in-place-solutions based on splice (AI,BI,CI) was fastest (sometimes ~100x - but it depends of array size)
  • for small arrays BI solution was slowest
  • for big arrays E solution was slowest

enter image description here

Details

Tests was divided into two groups: in-place solutions (AI,BI,CI) and non-in-place solutions (D,E,F) and was perform for two cases

  • test for array with 10 elements - you can run it HERE
  • test for array with 1.000.000 elements - you can run it HERE

Tested code is presented in below snippet

jsfiddle

_x000D_
_x000D_
function AI(arr, i, el) {
  arr.splice(i, 0, el);
  return arr;
}

function BI(arr, i, el) {
  Array.prototype.splice.apply(arr, [i, 0, el]);
  return arr;
}

function CI(arr, i, el) {
  Array.prototype.splice.call(arr, i, 0, el);
  return arr;
}

function D(arr, i, el) {
  return arr.slice(0, i).concat(el, arr.slice(i));
}

function E(arr, i, el) {
  return [...arr.slice(0, i), el, ...arr.slice(i)]
}

function F(arr, i, el) {
  return arr.reduce((s, a, j)=> (j-i ? s.push(a) : s.push(el, a), s), []);
}



// -------------
// TEST
// -------------

let arr = ["a", "b", "c", "d", "e", "f"];

let log = (n, f) => {
  let a = f([...arr], 3, "NEW");
  console.log(`${n}: [${a}]`);
};

log('AI', AI);
log('BI', BI);
log('CI', CI);
log('D', D);
log('E', E);
log('F', F);
_x000D_
This snippet only presents tested code (it not perform tests)
_x000D_
_x000D_
_x000D_

Example results for small array on chrome are below

enter image description here


Append Single Element at a specific index

//Append at specific position(here at index 1)
arrName.splice(1, 0,'newName1');
//1: index number, 0: number of element to remove, newName1: new element


//Append at specific position (here at index 3)
arrName[3] = 'newName1';

Append Multiple Element at a specific index

//Append from index number 1
arrName.splice(1, 0,'newElemenet1', 'newElemenet2', 'newElemenet3');
//1: index number from where append start, 
//0: number of element to remove, 
//newElemenet1,2,3: new elements

Array#splice() is the way to go, unless you really want to avoid mutating the array. Given 2 arrays arr1 and arr2, here's how you would insert the contents of arr2 into arr1 after the first element:

_x000D_
_x000D_
const arr1 = ['a', 'd', 'e'];_x000D_
const arr2 = ['b', 'c'];_x000D_
_x000D_
arr1.splice(1, 0, ...arr2); // arr1 now contains ['a', 'b', 'c', 'd', 'e']_x000D_
_x000D_
console.log(arr1)
_x000D_
_x000D_
_x000D_

If you are concerned about mutating the array (for example, if using Immutable.js), you can instead use slice(), not to be confused with splice() with a 'p'.

const arr3 = [...arr1.slice(0, 1), ...arr2, ...arr1.slice(1)];

Even though this has been answered already, I'm adding this note for an alternative approach.

I wanted to place a known number of items into an array, into specific positions, as they come off of an "associative array" (i.e. an object) which by definition is not guaranteed to be in a sorted order. I wanted the resulting array to be an array of objects, but the objects to be in a specific order in the array since an array guarantees their order. So I did this.

First the source object, a JSONB string retrieved from PostgreSQL. I wanted to have it sorted by the "order" property in each child object.

var jsonb_str = '{"one": {"abbr": "", "order": 3}, "two": {"abbr": "", "order": 4}, "three": {"abbr": "", "order": 5}, "initialize": {"abbr": "init", "order": 1}, "start": {"abbr": "", "order": 2}}';

var jsonb_obj = JSON.parse(jsonb_str);

Since the number of nodes in the object is known, I first create an array with the specified length:

var obj_length = Object.keys(jsonb_obj).length;
var sorted_array = new Array(obj_length);

And then iterate the object, placing the newly created temporary objects into the desired locations in the array without really any "sorting" taking place.

for (var key of Object.keys(jsonb_obj)) {
  var tobj = {};
  tobj[key] = jsonb_obj[key].abbr;

  var position = jsonb_obj[key].order - 1;
  sorted_array[position] = tobj;
}

console.dir(sorted_array);

Other than splice, you can use this approach which will not mutate the original array, but will create a new array with the added item. You should usually avoid mutation whenever possible. I'm using ES6 spread operator here.

_x000D_
_x000D_
const items = [1, 2, 3, 4, 5]_x000D_
_x000D_
const insert = (arr, index, newItem) => [_x000D_
  // part of the array before the specified index_x000D_
  ...arr.slice(0, index),_x000D_
  // inserted item_x000D_
  newItem,_x000D_
  // part of the array after the specified index_x000D_
  ...arr.slice(index)_x000D_
]_x000D_
_x000D_
const result = insert(items, 1, 10)_x000D_
_x000D_
console.log(result)_x000D_
// [1, 10, 2, 3, 4, 5]
_x000D_
_x000D_
_x000D_

This can be used to add more than one item by tweaking the function a bit to use the rest operator for the new items, and spread that in the returned result as well

_x000D_
_x000D_
const items = [1, 2, 3, 4, 5]_x000D_
_x000D_
const insert = (arr, index, ...newItems) => [_x000D_
  // part of the array before the specified index_x000D_
  ...arr.slice(0, index),_x000D_
  // inserted items_x000D_
  ...newItems,_x000D_
  // part of the array after the specified index_x000D_
  ...arr.slice(index)_x000D_
]_x000D_
_x000D_
const result = insert(items, 1, 10, 20)_x000D_
_x000D_
console.log(result)_x000D_
// [1, 10, 20, 2, 3, 4, 5]
_x000D_
_x000D_
_x000D_


Here's a working function that I uses in one of my application.

This checks if item exit

let ifExist = (item, strings = [ '' ], position = 0) => {
     // output into an array with empty string. Important just in case their is no item. 
    let output = [ '' ];
    // check to see if the item that will be positioned exist.
    if (item) {
        // output should equal to array of strings. 
        output = strings;
       // use splice in order to break the array. 
       // use positition param to state where to put the item
       // and 0 is to not replace an index. Item is the actual item we are placing at the prescribed position. 
        output.splice(position, 0, item);
    }
    //empty string is so we do not concatenate with comma or anything else. 
    return output.join("");
};

And then I call it below.

ifExist("friends", [ ' ( ', ' )' ], 1)}  // output: ( friends )
ifExist("friends", [ ' - '], 1)}  // output:  - friends 
ifExist("friends", [ ':'], 0)}  // output:   friends: 

I recommend using pure JavaScript in this case, also there is no insert method in JavaScript, but we have a method which is a built-in Array method which does the job for you, it's called splice...

Let's see what's splice()...

The splice() method changes the contents of an array by removing existing elements and/or adding new elements.

OK, imagine we have this array below:

const arr = [1, 2, 3, 4, 5];

We can remove 3 like this:

arr.splice(arr.indexOf(3), 1);

It will return 3, but if we check the arr now, we have:

[1, 2, 4, 5]

So far, so good, but how we can add a new element to array using splice? Let's put back 3 in the arr...

arr.splice(2, 0, 3);

Let's see what we have done...

We use splice again, but this time for the second argument, we pass 0, means we want to delete no item, but at the same time, we add third argument which is 3 that will be added at second index...

You should be aware, that we can delete and add at the same time, for example now we can do:

arr.splice(2, 2, 3);

Which will delete 2 items at index 2, then add 3 at index 2 and result will be:

[1, 2, 3, 5];

This is showing how each item in splice work:

array.splice(start, deleteCount, item1, item2, item3 ...)


Anyone who's still having issues with this one and have tried all the options above and never got it. I'm sharing my solution, this is to take consideration that you don't wan't to explicitly state the properties of your object vs the array.

function isIdentical(left, right){
    return JSON.stringify(left) === JSON.stringify(right);
}

function contains(array, obj){
    let count = 0;
    array.map((cur) => {
          if(this.isIdentical(cur, obj)) count++;
    });
    return count > 0;
}

This is a combination of iterating the reference array and comparing it to the object you wanted to check, convert both of them into a string then iterated if it matched. Then you can just count. This can be improved but this is where I settled. Hope this helps.


Immutable insertion

Using splice method is surely the best answer if you need to insert into an array in-place.

However, if you are looking for an immutable function that returns a new updated array instead of mutating the original array on insert, you can use the following function.

_x000D_
_x000D_
function insert(array, index) {
  const items = Array.prototype.slice.call(arguments, 2);

  return [].concat(array.slice(0, index), items, array.slice(index));
}

const list = ['one', 'two', 'three'];

const list1 = insert(list, 0, 'zero'); // Insert single item
const list2 = insert(list, 3, 'four', 'five', 'six'); // Insert multiple


console.log('Original list: ', list);
console.log('Inserted list1: ', list1);
console.log('Inserted list2: ', list2);
_x000D_
_x000D_
_x000D_

Note: This is a pre-ES2015 way of doing it so it works for both older and newer browsers.

If you're using ES6 then you can try out rest parameters too; see this answer.


Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to jquery

How to make a variable accessible outside a function? Jquery assiging class to th in a table Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Getting all files in directory with ajax Bootstrap 4 multiselect dropdown Cross-Origin Read Blocking (CORB) bootstrap 4 file input doesn't show the file name Jquery AJAX: No 'Access-Control-Allow-Origin' header is present on the requested resource how to remove json object key and value.?

Examples related to arrays

PHP array value passes to next row Use NSInteger as array index How do I show a message in the foreach loop? Objects are not valid as a React child. If you meant to render a collection of children, use an array instead Iterating over arrays in Python 3 Best way to "push" into C# array Sort Array of object by object field in Angular 6 Checking for duplicate strings in JavaScript array what does numpy ndarray shape do? How to round a numpy array?