I have a need to add or prepend elements at the beginning of an array.
For example, if my array looks like below:
[23, 45, 12, 67]
And the response from my AJAX call is 34
, I want the updated array to be like the following:
[34, 23, 45, 12, 67]
Currently I am planning to do it like this:
var newArray = [];
newArray.push(response);
for (var i = 0; i < theArray.length; i++) {
newArray.push(theArray[i]);
}
theArray = newArray;
delete newArray;
Is there a better way to do this? Does JavaScript have any built-in functionality that does this?
The complexity of my method is O(n)
and it would be really interesting to see better implementations.
12 Answers 12
Use unshift
. It's like push
, except it adds elements to the beginning of the array instead of the end.
unshift
/push
- add an element to the beginning/end of an arrayshift
/pop
- remove and return the first/last element of an array
A simple diagram...
unshift -> [array] <- push
shift <- [array] -> pop
and chart:
add | remove | start | end |
---|---|---|---|
push |
X | X | |
pop |
X | X | |
unshift |
X | X | |
shift |
X | X |
Check out the MDN Array documentation. Virtually every language that has the ability to push/pop elements from an array will also have the ability to unshift/shift (sometimes called push_front
/pop_front
) elements, you should never have to implement these yourself.
As pointed out in the comments, if you want to avoid mutating your original array, you can use concat
, which concatenates two or more arrays together. You can use this to functionally push a single element onto the front or back of an existing array; to do so, you need to turn the new element into a single element array:
const array = [3, 2, 1]
const newFirstElement = 4
const newArray = [newFirstElement].concat(array) // [ 4, 3, 2, 1 ]
console.log(newArray);
concat
can also append items. The arguments to concat
can be of any type; they are implicitly wrapped in a single-element array, if they are not already an array:
const array = [3, 2, 1]
const newLastElement = 0
// Both of these lines are equivalent:
const newArray1 = array.concat(newLastElement) // [ 3, 2, 1, 0 ]
const newArray2 = array.concat([newLastElement]) // [ 3, 2, 1, 0 ]
console.log(newArray1);
console.log(newArray2);
-
70Using
concat
might be preferable as it returns the new array. Very useful for chaining.[thingToInsertToFront].concat(originalArray).reduce(fn).reverse().map(fn)
etc... If you useunshift
, you can't do that chaining because all you get back is the length.user5900250– user59002502016年09月23日 18:27:55 +00:00Commented Sep 23, 2016 at 18:27 -
13shift/unshift, push/pop, splice. Very logical names for such methods.linuxunil– linuxunil2018年04月25日 12:32:27 +00:00Commented Apr 25, 2018 at 12:32
array operations image
var a = [23, 45, 12, 67];
a.unshift(34);
console.log(a); // [34, 23, 45, 12, 67]
-
205The reason why people need a visual guideline for 4 everyday used functions is because of the encrypted function names... Why is unshift not called Insert? Shift should be Remove. etc...Pascal– Pascal2013年06月29日 21:24:32 +00:00Commented Jun 29, 2013 at 21:24
-
102//Why is unshift not called Insert?// It comes from the conventions of the C programming language where array elements were treated like a stack. (see perlmonks.org/?node_id=613129 for a complete explanation)dreftymac– dreftymac2013年07月26日 21:05:24 +00:00Commented Jul 26, 2013 at 21:05
-
43@Pascal No, insert and remove would be particularly bad names for this; they imply random access, instead of adding/removing from the front of the array2013年10月22日 13:06:49 +00:00Commented Oct 22, 2013 at 13:06
-
34I would have thought that unshift should remove the first key, and shift would insert at the first key, but that's just my general thoughtShannon Hochkins– Shannon Hochkins2014年09月25日 01:50:21 +00:00Commented Sep 25, 2014 at 1:50
-
7Mind that
[23, 45, 12, 67].unshift(34)
will not work. The Array must first be saved inside a variable, becauseunshift
itself returns a value.vsync– vsync2017年03月15日 15:12:27 +00:00Commented Mar 15, 2017 at 15:12
With ES6, use the spread operator ...
:
Demo
var arr = [23, 45, 12, 67];
arr = [34, ...arr]; // RESULT : [34, 23, 45, 12, 67]
console.log(arr)
-
34also creates a new array, useful for pure functionsdevonj– devonj2017年08月08日 19:01:03 +00:00Commented Aug 8, 2017 at 19:01
-
2what is the performance implication here? Is it slower than using unshift()?Peter T.– Peter T.2018年03月02日 09:49:14 +00:00Commented Mar 2, 2018 at 9:49
-
1Sure, it will be slower since it is an immutable array ( creating a new array). If you are working with a big array or the performance is your first requirement, please consider to use
concat
instead.Abdennour TOUMI– Abdennour TOUMI2018年03月02日 15:42:59 +00:00Commented Mar 2, 2018 at 15:42 -
1@AbdennourTOUMI Just to clarify your comment. It is not creating an immutable array, it is just creating a new array without mutating the existing one.Flimm– Flimm2021年11月11日 11:38:45 +00:00Commented Nov 11, 2021 at 11:38
-
2@stackdave Of course performance is important in 2018 (2022). It may not be important in your todo app or webshop UI with 20 elements, but it's important in my graphics editor with 500 MB typed arrays.John Weisz– John Weisz2022年11月07日 15:00:00 +00:00Commented Nov 7, 2022 at 15:00
Another way to do that is through concat
:
var arr = [1, 2, 3, 4, 5, 6, 7];
console.log([0].concat(arr));
The difference between concat
and unshift
is that concat
returns a new array. The performance between them could be found here.
function fn_unshift() {
arr.unshift(0);
return arr;
}
function fn_concat_init() {
return [0].concat(arr)
}
Here is the test result:
-
It would be good for your answer to append the performance comparison of both apart from adding the reference.Ivan De Paz Centeno– Ivan De Paz Centeno2016年06月15日 09:12:24 +00:00Commented Jun 15, 2016 at 9:12
-
I just got jsPerf is temporarily unavailable while we’re working on releasing v2. Please try again later from the link. Another good reason to include the results instead of linking to them.Tigger– Tigger2016年08月21日 01:00:49 +00:00Commented Aug 21, 2016 at 1:00
-
jsPref result:
unshift
: 25,510 ±3.18% 99% slowerconcat
: 2,436,894 ±3.39% fastestIlluminator– Illuminator2016年11月03日 10:28:26 +00:00Commented Nov 3, 2016 at 10:28 -
In the latest Safari, fn_unshift() runs faster.passatgt– passatgt2017年07月21日 13:22:55 +00:00Commented Jul 21, 2017 at 13:22
-
In the latest Safari (v 10), fn_unshift() is slower again.rmcsharry– rmcsharry2017年11月09日 11:22:31 +00:00Commented Nov 9, 2017 at 11:22
Quick Cheatsheet:
The terms shift/unshift and push/pop can be a bit confusing, at least to folks who may not be familiar with programming in C.
If you are not familiar with the lingo, here is a quick translation of alternate terms, which may be easier to remember:
* array_unshift() - (aka Prepend ;; InsertBefore ;; InsertAtBegin )
* array_shift() - (aka UnPrepend ;; RemoveBefore ;; RemoveFromBegin )
* array_push() - (aka Append ;; InsertAfter ;; InsertAtEnd )
* array_pop() - (aka UnAppend ;; RemoveAfter ;; RemoveFromEnd )
Using ES6 destructuring (avoiding mutation off the original array):
const newArr = [item, ...oldArr]
-
8Essentially a duplicate answer of the one by Abdennour TOUMI...Jerry– Jerry2020年07月14日 08:08:13 +00:00Commented Jul 14, 2020 at 8:08
-
Don't. Spread-operator and creating a new array gets slow really fast.ABaumstumpf– ABaumstumpf2025年04月22日 10:27:47 +00:00Commented Apr 22 at 10:27
You have an array: var arr = [23, 45, 12, 67];
To add an item to the beginning, you want to use splice
:
var arr = [23, 45, 12, 67];
arr.splice(0, 0, 34)
console.log(arr);
-
arr.splice(0, arr.length, 34);Lior Elrom– Lior Elrom2015年10月15日 20:08:23 +00:00Commented Oct 15, 2015 at 20:08
-
1@LiorElrom what does your snippet do?Janus Troelsen– Janus Troelsen2016年06月22日 11:31:39 +00:00Commented Jun 22, 2016 at 11:31
-
@poushy it's browser specific, in Firefox 54 is
unshift
50% faster (but mostly more readable)Juraj– Juraj2017年05月17日 07:16:39 +00:00Commented May 17, 2017 at 7:16 -
@poushy Not anymore. Way slower.Andrew– Andrew2019年09月12日 16:15:19 +00:00Commented Sep 12, 2019 at 16:15
Without Mutating
Actually, all unshift
/push
and shift
/pop
mutate the source array.
The unshift
/push
add an item to the existed array from begin/end and shift
/pop
remove an item from the beginning/end of an array.
But there are few ways to add items to an array without a mutation. the result is a new array, to add to the end of array use below code:
const originArray = ['one', 'two', 'three'];
const newItem = 4;
const newArray = originArray.concat(newItem); // ES5
const newArray2 = [...originArray, newItem]; // ES6+
To add to begin of original array use below code:
const originArray = ['one', 'two', 'three'];
const newItem = 0;
const newArray = (originArray.slice().reverse().concat(newItem)).reverse(); // ES5
const newArray2 = [newItem, ...originArray]; // ES6+
With the above way, you add to the beginning/end of an array without a mutation.
-
I just put an
slice
function at the end oforiginArray
to prevent it from mutability.Ahmad Khani– Ahmad Khani2019年12月04日 07:34:29 +00:00Commented Dec 4, 2019 at 7:34 -
1Awesome! When comes to (Redux) State management... this answer is precious!Pedro Ferreira– Pedro Ferreira2020年02月23日 13:16:07 +00:00Commented Feb 23, 2020 at 13:16
-
[newItem, ...originArray]; // ES6+ Is great syntax ! Worked perfect !! thanks.Bat– Bat2021年10月13日 07:28:07 +00:00Commented Oct 13, 2021 at 7:28
Cheatsheet to prepend new element(s) into the array
const list = [23, 45, 12, 67];
list.unshift(34);
console.log(list); // [34, 23, 45, 12, 67];
2. Array#splice
const list = [23, 45, 12, 67];
list.splice(0, 0, 34);
console.log(list); // [34, 23, 45, 12, 67];
const list = [23, 45, 12, 67];
const newList = [34, ...list];
console.log(newList); // [34, 23, 45, 12, 67];
4. Array#concat
const list = [23, 45, 12, 67];
const newList = [32].concat(list);
console.log(newList); // [34, 23, 45, 12, 67];
Note: In each of these examples, you can prepend multiple items by providing more items to insert.
If you need to continuously insert an element at the beginning of an array, it is faster to use push
statements followed by a call to reverse
, instead of calling unshift
all the time.
Benchmark test: http://jsben.ch/kLIYf
-
2Note: initial array should be empty.192kb– 192kb2019年08月15日 10:12:11 +00:00Commented Aug 15, 2019 at 10:12
-
In 2021 your benchmark shows a comprehensive win for
unshift
across all major desktop browsers (at least on this Mac).Olly Hodgson– Olly Hodgson2021年07月07日 21:52:07 +00:00Commented Jul 7, 2021 at 21:52 -
@OllyHodgson testing on Ubuntu Linux with Firefox: reverse solution is 3-times faster.Krisztián Balla– Krisztián Balla2021年11月06日 10:22:10 +00:00Commented Nov 6, 2021 at 10:22
Using splice
we insert an element to an array at the begnning:
arrName.splice( 0, 0, 'newName1' );
If you want to push elements that are in an array at the beginning of your array, use <func>.apply(<this>, <Array of args>)
:
const arr = [1, 2];
arr.unshift.apply(arr, [3, 4]);
console.log(arr); // [3, 4, 1, 2]
push
statements followed by a call toreverse
, instead of callingunshift
all the time.