如何在Javascript数组的开头添加新的数组元素?


1583

我需要在数组的开头添加或添加元素。

例如,如果我的数组如下所示:

[23, 45, 12, 67]

我的AJAX调用的响应是34,我希望更新后的数组如下所示:

[34, 23, 45, 12, 67]

目前,我正在计划这样做:

var newArray = [];
newArray.push(response);

for (var i = 0; i < theArray.length; i++) {
    newArray.push(theArray[i]);
}

theArray = newArray;
delete newArray;

有什么更好的方法吗?Javascript是否具有执行此操作的任何内置功能?

我的方法很复杂,O(n)看到更好的实现将非常有趣。


9
仅供参考:如果您需要在数组的开头连续插入一个元素,则使用push语句后再调用会更快reverse,而不是一直调用unshift
珍妮·奥莱利

2
@ JennyO'Reilly,您应该将其发布为答案。与我的用例完美匹配。谢谢
rob

2
性能测试:jsperf.com/adding-element-to-the-array-start 但每种浏览器的结果都不同。
Avernikoz

Answers:


2810

使用unshift。就像一样push,除了它在数组的开头而不是结尾添加元素。

  • unshift// push-将元素添加到数组的开头/结尾
  • shift// pop -删除并返回数组的第一个/最后一个元素

一个简单的图...

   unshift -> array <- push
   shift   <- array -> pop

和图表:

          add  remove  start  end
   push    X                   X
    pop           X            X
unshift    X             X
  shift           X      X

查看MDN阵列文档。实际上,每种能够从数组中推入/弹出元素的语言都将具有取消/移入(有时称为push_front/ pop_front)元素的能力,您不必自己实现这些。


如注释中所指出的那样,如果要避免更改原始数组,可以使用concat将两个或更多数组连接在一起的。您可以使用它在功能上将单个元素推到现有数组的前面或后面;为此,您需要将新元素转换为单个元素数组:

const array = [ 3, 2, 1 ]

const newFirstElement = 4

const newArray = [newFirstElement].concat(array) // [ 4, 3, 2, 1 ]

concat也可以附加项目。的参数concat可以是任何类型;如果它们还不是数组,则将它们隐式包装在单元素数组中:

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 ]

51
使用它concat可能会更好,因为它会返回新数组。对于链接非常有用。 [thingToInsertToFront].concat(originalArray).reduce(fn).reverse().map(fn)等等...如果使用unshift,则无法进行链接,因为返回的只是长度。
StJohn3D

4
移位/不移位,推动/弹出,拼接。这种方法的名称很合逻辑。
linuxunil '18

1396

阵列运算图

var a = [23, 45, 12, 67];
a.unshift(34);
console.log(a); // [34, 23, 45, 12, 67]


117
人们需要4条日常使用功能的视觉指南的原因是由于功能名称已加密...为什么unshift不称为Insert?班次应删除。等等...
Pascal

76
//为什么unshift不被称为Insert?//它来自C编程语言的约定,在该约定中,数组元素被视为堆栈。(见perlmonks.org/?node_id=613129为一个完整的解释)
dreftymac

25
@Pascal不行,插入和删除将对此特别糟糕;他们暗示着随机访问,而不是从阵列的前面添加/删除
meagar

25
我本来以为不印字应该删除第一个键,然后转变将在第一键插入,不过这只是我的总体思路
香农Hochkins

27
我喜欢的DNA参考
亨特Webdev的

235

对于ES6,请使用传播运算符...

演示

var arr = [23, 45, 12, 67];
arr = [34, ...arr]; // RESULT : [34,23, 45, 12, 67]

console.log(arr)


19
还创建了一个对纯函数有用的新数组
devonj

这里的性能含义是什么?它比使用unshift()慢吗?
Peter T.

1
当然,由于它是一个不可变的数组(创建一个新数组),所以速度会变慢。如果您要处理大型阵列,或者性能是您的首要要求,请考虑concat改用。
Abdennour TOUMI

在2018年性能并不重要,浏览器和节点中的新版本具有相同的性能
stackdave

75

另一种方式来做到这一点 concat

var arr = [1, 2, 3, 4, 5, 6, 7];
console.log([0].concat(arr));

concat和之间的区别unshiftconcat返回一个新数组。他们之间的表现可以在这里找到。

function fn_unshift() {
  arr.unshift(0);
  return arr;
}

function fn_concat_init() {
  return [0].concat(arr)
}

这是测试结果

在此处输入图片说明


除了添加参考之外,最好将两者的性能比较都附加到您的答案中。
伊万·德·帕兹

我刚得到jsPerf,在我们发布v2的过程中暂时不可用。请稍后通过链接重试。包含结果而不是链接到结果的另一个很好的理由。
Tigger

jsPref结果:: unshift25,510±3.18%较慢99% concat:最快2,436,894±3.39%
Illuminator

在最新的Safari中,fn_unshift()运行得更快。
passatgt

在最新的Safari(v 10)中,fn_unshift()再次变慢。
rmcsharry17年

45

快速备忘单:

术语“移位/不移位”和“推入/弹出”可能会有些混乱,至少对于那些可能不熟悉C编程的人而言。

如果您对术语不熟悉,可以使用以下快速翻译的替代术语,这样可能更容易记住:

* array_unshift()  -  (aka Prepend ;; InsertBefore ;; InsertAtBegin )     
* array_shift()    -  (aka UnPrepend ;; RemoveBefore  ;; RemoveFromBegin )

* array_push()     -  (aka Append ;; InsertAfter   ;; InsertAtEnd )     
* array_pop()      -  (aka UnAppend ;; RemoveAfter   ;; RemoveFromEnd ) 

20

你有一个数组: var arr = [23, 45, 12, 67];

要将项目添加到开头,请使用splice

var arr = [23, 45, 12, 67];
arr.splice(0, 0, 34)
console.log(arr);


arr.splice(0,arr.length,34);
Lior Elrom

1
@LiorElrom您的代码段做什么?
Janus Troelsen

@poushy是特定于浏览器的,在Firefox 54中unshift速度提高了50%(但更具可读性)
icl7126

@poushy不再了。慢一点
安德鲁(Andrew)

17

没有突变

实际上,所有的unshift/ pushshift/ pop 发生变异的来源阵列。

unshift/ push将项目添加到从开始/结束和存在阵列shift/ pop从数组的开始/结束删除项目。

但是,几乎没有任何方法可以在没有突变的情况下将项目添加到数组中。结果是一个新数组,要添加到数组末尾,请使用以下代码:

const originArray = ['one', 'two', 'three'];
const newItem = 4;

const newArray = originArray.concat(newItem); // ES5
const newArray2 = [...originArray, newItem]; // ES6+

要添加到原始数组的开头,请使用以下代码:

const originArray = ['one', 'two', 'three'];
const newItem = 0;

const newArray = (originArray.slice().reverse().concat(newItem)).reverse(); // ES5
const newArray2 = [newItem, ...originArray]; // ES6+

通过上述方法,您无需更改即可添加到数组的开头/结尾。


我只是将一个slice函数放在末尾originArray以防止其可变性。
艾哈迈德·卡尼

1
太棒了!当谈到(Redux)状态管理时...这个答案很宝贵!
Pedro Ferreira

1
这是正确的方法!
mmm

10

使用ES6解构:(避免对原始数组进行突变)

const newArr = [item, ...oldArr]




5

使用splice我们在开始时将元素插入数组:

arrName.splice( 0, 0, 'newName1' );

这是正确的答案。谢谢Srikrushna
Khanh Tran
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.