4276

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.

4
  • 156
    Note that JQuery is a DOM and event manipulation library, not a language of its own. It has nothing to do with array manipulation.
    – Domino
    Commented Feb 18, 2015 at 15:36
  • 36
    api.jquery.com/jQuery.inArray has nothing to do with the DOM or events. jQuery has evolved into a mixed toolkit for in browser JS development, leading to people expecting it to have a method for everything.
    – Tim
    Commented Apr 14, 2016 at 8:14
  • 8
    @Tim, But it's still not a language of its own (still there are some questions like "how to sum two numbers in jQuery" here on SO)
    – Victor
    Commented May 7, 2018 at 13:31
  • 10
    @Victor No, and never will be. jQuery was useful and relevant, but it's had its day.
    – Tim
    Commented May 8, 2018 at 6:17

34 Answers 34

6762

You want the splice function on the native array object.

arr.splice(index, 0, item); will insert item into arr at the specified index (deleting 0 items first, that is, it's just an insert).

In this example we will create an array and add an element to it into index 2:

var arr = [];
arr[0] = "Jani";
arr[1] = "Hege";
arr[2] = "Stale";
arr[3] = "Kai Jim";
arr[4] = "Borge";

console.log(arr.join()); // Jani,Hege,Stale,Kai Jim,Borge
arr.splice(2, 0, "Lene");
console.log(arr.join()); // Jani,Hege,Lene,Stale,Kai Jim,Borge

UPDATE (24 May 2024)

You can now use the toSpliced method which behaves just like splice, however it returns a new array without mutating the existing one.

You could update the previous example like so:

const updated = arr.toSpliced(2, 0, "Lene");
18
  • 266
    Thanks, I thought I would feel stupid for asking but now that I know the answer I don't! Why on earth did they decide to call it splice when a more searchable term was in common use for the same function?!
    – tags2k
    Commented Feb 25, 2009 at 14:46
  • 109
    @tags2k: because the function does more than inserting items and it's name was already established in perl?
    – Christoph
    Commented Feb 25, 2009 at 14:53
  • 18
    doc: developer.mozilla.org/en/JavaScript/Guide/…
    – Dingo
    Commented Mar 10, 2011 at 9:54
  • 76
    Splice can insert, but just as frequently does not. For example: arr.splice(2,3) will remove 3 elements starting at index 2. Without passing the 3rd....Nth parameters nothing is inserted. So the name insert() doesn't do it justice either.
    – EBarr
    Commented May 13, 2014 at 1:45
  • 23
    I think the term "splice" makes sense. Splice means to join or connect, also to change. You have an established array that you are now "changing" which would involve adding or removing elements. You specify where in the array to start, then how many old items to remove (if any) and lastly, optionally a list of new elements to add. Splice is also a great sci-fi term of course. Commented Nov 21, 2014 at 15:45
424

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

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

Then you can use it like:

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

// => arr == [ 'A', 'B', 'C', 'D', 'E' ]
11
  • 18
    To insert multiple items you can use Array.prototype.insert = function (index, items) { this.splice.apply(this, [index, 0].concat(items)); }
    – Ryan Smith
    Commented May 30, 2014 at 12:15
  • 11
    The problem with adding stuff to array is that the function will show up as an element when you do for(i in arr) {...}
    – rep_movsd
    Commented Jul 2, 2014 at 9:38
  • 27
    But keep in mind that it's not recommended to extend native types since it might interfere with other code or future functionality.
    – marsze
    Commented Aug 21, 2018 at 9:48
  • 104
    Don’t modify objects you don’t own Commented Feb 19, 2019 at 18:09
  • 41
    Don't modify prototypes
    – satya164
    Commented May 31, 2019 at 12:54
307

Other than splice, you can use this approach which will not mutate the original array, but it will create a new array with the added item. It is useful, when you need to avoid mutation. I'm using the ES6 spread operator here.

const items = [1, 2, 3, 4, 5]

const insert = (arr, index, newItem) => [
  // part of the array before the specified index
  ...arr.slice(0, index),
  // inserted item
  newItem,
  // part of the array after the specified index
  ...arr.slice(index)
]

const result = insert(items, 1, 10)

console.log(result)
// [1, 10, 2, 3, 4, 5]

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:

const items = [1, 2, 3, 4, 5]

const insert = (arr, index, ...newItems) => [
  // part of the array before the specified index
  ...arr.slice(0, index),
  // inserted items
  ...newItems,
  // part of the array after the specified index
  ...arr.slice(index)
]

const result = insert(items, 1, 10, 20)

console.log(result)
// [1, 10, 20, 2, 3, 4, 5]

6
  • 4
    Is this a good, safe way to do this? I ask because this seems so elegant and concise but no other answers touch upon this. Most of them modify the prototype object!
    – anotherDev
    Commented Dec 11, 2017 at 9:32
  • 11
    @HarshKanchina That's probably because most of the answers are pre ES6, but this approach is very common now from my experience
    – gafi
    Commented Dec 16, 2017 at 22:35
  • 2
    This approach will always be slower and worse than splice. Don't be fooled by the pretty sugar syntax or the popularity among other misguided devs (*cough* gafi *cough*). Allocating a whole new array and discarding the old array is way slower than modifying the original array. If you need a copy, then call slice() before splice(). Never use the ES6 for such trivial things which can be done far better and far more cleanly with other APIs.
    – Jack G
    Commented Jan 19, 2021 at 2:19
  • 5
    You should explain WHY you should avoid mutation. Is it slow? If so, how much slower? Is it worth the extra "hassle"? Commented May 25, 2021 at 9:34
  • 5
    @JackG don't forget that slice() will allocate a new array, and indeed, splice() allocates a new array too since it returns an array of the items that were removed (an empty array in this case). Running a benchmark on these cases shows that splice is quicker (by ~30%), but we're in the range of millions of operations per second, so unless your application is doing a lot of these operations in a tight loop, it's not going to make any difference.
    – nickf
    Commented Sep 22, 2021 at 9:00
94

Using Array.prototype.splice() is one elegant way of achieving it

const numbers = ['one', 'two', 'four', 'five']
numbers.splice(2, 0, 'three');

console.log(numbers)

Read more about Array.prototype.splice

1
  • 1
    As stated above, using prototype will add an extra item to the array, so the loops won't work as expected after. Commented Aug 29, 2023 at 17:11
90

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/

9
  • Is there a compact way to have this version also merge an array when it finds one in the arguments?
    – Nolo
    Commented Mar 30, 2013 at 23:56
  • I don't understand the first result ["b", "X", "Y", "Z", "c"]. Why isn't "d" included? It seems to me that if you put 6 as the second parameter of slice() and there are 6 elements in the array starting from the specified index, then you should get all 6 elements in the return value. (The doc says howMany for that parameter.) developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… Commented Dec 12, 2014 at 2:03
  • Actually, if I use an index of 3 or more, I get nothing in the output (case 1., FireFox) ["a", "b", "c", "d"].insert(2, "X", "Y", "Z").slice(3, 3); => [ ] Commented Dec 12, 2014 at 2:08
  • @AlexisWilke In the first example I used slice method and not splice, which you're referring to in the comment. Second parameter of slice (named end) is zero-based index at which to end extraction. slice extracts up to but not including end. Hence after insert you have ["a", "b", "X", "Y", "Z", "c", "d"], from which slice extracts elements with indices from 1 up to 6, i.e. from "b" to "d" but not including "d". Does it make sense?
    – VisioN
    Commented Dec 12, 2014 at 8:46
  • For some reason, when I go to use insert2, i get an "Expected 1 argument, but got 2" exception.
    – Corné
    Commented Jun 26, 2020 at 3:08
56

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 yourself: 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);
4
  • 2
    Wouldn't insertAt() do better to call insertArrayAt() once it has created a single-element arrayToInsert? That avoids repetition of identical code.
    – Matt Sach
    Commented Sep 10, 2012 at 16:12
  • 1
    this is a great example of when to use 'apply'
    – CRice
    Commented Jan 29, 2015 at 0:44
  • I added a removeCount parameter to this method to take advantages of splice's ability to also remove items at that index: Array.prototype.splice.apply(array, [index, removeCount || 0].concat(arrayToInsert));
    – CRice
    Commented Jan 29, 2015 at 0:56
  • Thank alot and i use it in qml
    – S At
    Commented Aug 1, 2022 at 15:03
47

Solutions & Performance

Today (2020.04.24) I perform tests for chosen solutions for big and small arrays. I tested them on macOS v10.13.6 (High Sierra) on Chrome 81.0, Safari 13.1, and 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, and CI) was fastest (sometimes ~100x - but it depends on the array size)
  • for small arrays the BI solution was slowest
  • for big arrays the E solution was slowest

Enter image description here

Details

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

  • test for an array with 10 elements - you can run it here
  • test for an array with 1,000,000 elements - you can run it here

Tested code is presented in the below snippet:

jsfiddle

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);
This snippet only presents tested code (it not perform tests)

Example results for a small array on Google Chrome are below:

Enter image description here

3
  • 4
    The answer doesn't address the OP's question. Commented Sep 12, 2020 at 5:52
  • 27
    @kabirbaidhya actually in this answer you can find many solutions to OP question, but additional value in this answer is performance comparison between them - I hope many people will find it useful Commented Sep 12, 2020 at 7:24
  • 3
    Perhaps, you may want to restructure your answer a bit so that it's intuitive for the users to see the possible solutions first and their performance implications later. It looks primarily focused on performance rn. Commented Sep 12, 2020 at 7:46
47

You can use splice() for that

The splice() method usually receives three arguments when adding an element:

  1. the index of the array where the item is going to be added
  2. the number of items to be removed, which in this case is 0
  3. the element to add

let array = ['item 1', 'item 2', 'item 3']
let insertAtIndex = 0
let itemsToRemove = 0
    
array.splice(insertAtIndex, itemsToRemove, 'insert this string at index 0')

console.log(array)

3
  • 2
    next time read the answers please, this solution was already given. You are just repeating information.
    – vdegenne
    Commented May 31, 2022 at 9:57
  • 7
    @vdegenne when I posted this answer, I thought the other answers could be better explained. The amount of votes up is a clear indicator that the answer has ben useful for some.
    – Gass
    Commented May 31, 2022 at 11:31
  • 3
    Yes, explaining the meaning of the second parameter is especially helpful
    – djna
    Commented Sep 23, 2022 at 5:01
40

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

Array.prototype.insert = function(i,...rest){
  this.splice(i,0,...rest)
  return this
}

var a = [3,4,8,9];
document.write("<pre>" + JSON.stringify(a.insert(2,5,6,7)) + "</pre>");

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;

Array.prototype.insert = function(i,...rest){
  return this.slice(0,i).concat(rest,this.slice(i));
}

var a = [3,4,8,9],
    b = a.insert(2,5,6,7);
console.log(JSON.stringify(a));
console.log(JSON.stringify(b));

4
  • 4
    "a totally meaningless empty array" - 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. Given that you're adding to a prototype, and splice mutates the original array, I don't think "proper functional programming" belongs anywhere in the vicinity of splice. Commented May 22, 2016 at 21:15
  • We are talking about insert here and the second parameter of Array.prototype.splice() has to be zero. And what it returns have no meaning other than "i have not deleted anything" and since we use it for inserting an item we already have that information. If you don't want to mutate the original array then you can do the same with two Array.prototype.slice() and one Array.prototype.concat() operations. It's up to you.
    – Redu
    Commented May 22, 2016 at 21:23
  • 1
    Your second implementation is the cleanest from this whole page and you have zero votes. Please take mine and keep up the good work. (you should just avoid mutating the prototype but you already know that)
    – NiKo
    Commented Jun 2, 2016 at 14:18
  • 1
    I think it is worth mentioning that the rest parameter is new ECMA 6th (developer.mozilla.org/en/docs/Web/JavaScript/Reference/… )
    – Geza Turi
    Commented Dec 9, 2016 at 17:02
33

I recommend using pure JavaScript in this case. Also there isn't any 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, meaning we don't want to delete any item, but at the same time, we add a third argument which is the 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 two items at index 2. Then add 3 at index 2 and the result will be:

[1, 2, 3, 5];

This is showing how each item in splice work:

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

1
  • 2
    Thanks for explaining in future i suggest using non digit numbers for the array values, for showing an example. Eg: arr.splice(2, 0, 3) vs arr.splice(2, 0, "C"). Easier for the reader to comprehend which argument maps to the value part and which one maps to the index part. Thank you! Commented Oct 9, 2020 at 14:47
24

Here are two ways:

const array = [ 'My', 'name', 'Hamza' ];

array.splice(2, 0, 'is');

console.log("Method 1: ", array.join(" "));

Or

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

const array = [ 'My', 'name', 'Hamza' ];
array.insert(2, 'is');

console.log("Method 2 : ", array.join(" "));

23

Append a single element at a specific index:

// Append at a 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 a specific position (here at index 3)
arrName[3] = 'newName1';

Append multiple elements 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
7
  • 11
    Worth noticing that arrName[3] does not append, it overrides. Commented Sep 10, 2018 at 22:40
  • It add the element to the existing array not over ride, Ex: let arrName = ['xxx', 'yyy', 'zzz']; arrName.splice(1, 0,'aaa', 'bbb', 'ccc'); after print the arrName
    – Srikrushna
    Commented Sep 12, 2018 at 18:49
  • If arrName has more than 3 elements you are overriding the 3rd, not appending. Or am I looking this at the wrong way? Commented Sep 12, 2018 at 18:51
  • If we insert an element on the middle, it shift the next element not overide. Please specify your problem, what you need. Take an array(example) and what you need on the output. plz comment me
    – Srikrushna
    Commented Sep 12, 2018 at 18:56
  • 2
    @Srikrushna arrName[3] = 'newName1'; will append if the array has only 3 elements. If there is an element in index 3, this will be replaced. If you want to append at end, it is better to use arrName.push('newName1');
    – awe
    Commented Nov 14, 2019 at 8:24
17

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:

const arr1 = ['a', 'd', 'e'];
const arr2 = ['b', 'c'];

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

console.log(arr1)

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

Another possible solution, with usage of Array.reduce.

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))

10

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);
0
10

Immutable insertion

Using the 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.

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

Note: This is a pre-ES6 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.

8

Anyone who's still having issues with this one and have tried all the options in previous answers and never got it. I'm sharing my solution, and this is to take into consideration that you don't want 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, converting both of them into a string, and then iterating if it matched. Then you can just count. This can be improved, but this is where I settled.

8

Taking profit of the reduce method as follows:

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 in this way we can return a new array (will be a cool functional way - more much better than using 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.

7

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 parameter, defines the number of elements from the index to be removed. item contains the new entries which you want to make in the array. It can be one or more than one.

initialArr.splice(2, 0, "Nigeria");
initialArr.splice(2, 0, "Australia","UK");
1
  • 4
    simply copy pasted the answer above. this is not adding any value to the question. either you add a new answer or comment on existing. please try to contribute something new. we dont want to spoil this community Commented Oct 24, 2017 at 6:50
6

I have to agree with Redu's answer 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 kind of nonsense IMHO. If the intention of the method was to "cut out a set of elements" and that was its 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.

It 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.

6

You can do it with array.splice:

/**
 * @param arr:  Array
 * @param item:  item to insert
 * @param index: index at which to insert 
 * @returns array with the inserted element
 */
export function _arrayInsertAt<T>(arr: T[], item: T, index: number) {
    return  arr.splice(index, 0, item);; 
}

Doc of array.slice

5

Here's a working function that I use in one of my applications.

This checks if an item exists:

let ifExist = (item, strings = [ '' ], position = 0) => {
     // Output into an array with an empty string. Important just in case their isn't any item.
    let output = [ '' ];
    // Check to see if the item that will be positioned exist.
    if (item) {
        // Output should be equal to an array of strings.
        output = strings;
       // Use splice() in order to break the array.
       // Use positional parameters 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:
1
  • Can you explain your solution please ?
    – De Bonheur
    Commented Sep 12, 2022 at 10:13
5

I like a little safety and I use this:

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)

2
  • 6
    You said you like safety, then suggest to modify basic prototype! logic? no
    – blazkovicz
    Commented Jan 11, 2021 at 13:01
  • 3
    yep .. it is m y definition of safety .. lol Commented Jan 27, 2021 at 5:00
3

If you want to keep the original array untouched but return a new array with the element inserted into a particular index you can use the new .toSpliced() method:

This avoids mutating the array in place:

//                0    1    2
const letters = ["A", "B", "D"];
const insertIndex = 2; // position in the array to insert 
const correctLetters = letters.toSpliced(insertIndex, 0, "C"); // 0 means don't delete any items, just insert. "C" is the item you want to insert.
console.log(correctLetters); // ["A", "B", "C", "D"] (new array contains new char)
console.log(letters); // ["A", "B", "D"] (unmodified)

If you need to insert multiple items into the array, just like its sibling .splice(), you can use .toSpliced() with multiple arguments:

.toSpliced(insertIndex, 0, "C", "D", "E");

The above, for example, will insert "C", "D", and "E" at insertIndex into the array without modifying it, returning a new array instead.

0
3

There's now the ToSpliced method.

const months = ["Jan", "Mar", "Apr", "May"];

// Inserting an element at index 1
const months2 = months.toSpliced(1, 0, "Feb");
1
  • A non-in-place version of 'splice': love it!
    – rubebop
    Commented May 2 at 9:25
2
//Suppose we have an array  
let myArray = [2, 4, 6, 8, 10];  

// Index where we want to insert the item  
let indexToInsert = 3;  

// Item we want to insert  
let itemToInsert = 174;  

// Now we Using splice() method to insert the item at the specified index  
myArray.splice(indexToInsert, 0, itemToInsert);  

// output with new value    
console.log(myArray);  
1
  • Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
    – Community Bot
    Commented Aug 9, 2023 at 12:54
1

Here is the modern (Typescript functional) way:

export const insertItemInList = <T>(
  arr: T[],
  index: number,
  newItem: T
): T[] => [...arr.slice(0, index), newItem, ...arr.slice(index)]
1

I do it like so:

const insert = (what, where, index) => 
  ([...where.slice(0, index), what , ...where.slice(index, where.length)]);

const insert = (what, where, index) =>
  ([...where.slice(0, index), what , ...where.slice(index, where.length)]);
  
const list = [1, 2, 3, 4, 5, 6];
const newList = insert('a', list, 2);

console.log(newList.indexOf('a') === 2);

1

Here's a simple function that supports inserting multiple values at the same time:

function add_items_to_array_at_position(array, index, new_items)
{
    return [...array.slice(0, index), ...new_items, ...array.slice(index)];
}

Usage example:

let old_array = [1,2,5];

let new_array = add_items_to_array_at_position(old_array, 2, [3,4]);

console.log(new_array);

//Output: [1,2,3,4,5]
1
  • This is similar to many of the existing answers but with a concise combination of function / spread operator / multiple items / example / output that hasn't been posted yet. Commented Mar 13, 2022 at 8:33
1
var array= [10,20,30,40]

var i;

var pos=2; //pos=index + 1
/*pos is position which we want to insert at which is index + 1.position two in an array is index 1.*/

var value=5 
//value to insert

//Initialize from last array element

for(i=array.length-1;i>=pos-1;i--){

array[i+1]=array[i]

}

array[pos-1]=value

console.log(array)
1
  • 2
    As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
    – Community Bot
    Commented Jul 25, 2022 at 11:31

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