我需要在数组的开头添加或添加元素。
例如,如果我的数组如下所示:
[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)
,看到更好的实现会很有趣。
push
语句然后调用 reverse
会更快,而不是一直调用 unshift
。
使用 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 Array documentation。几乎每一种能够从数组中推送/弹出元素的语言也都能够取消移位/移位(有时称为 push_front
/pop_front
)元素,您永远不必自己实现这些。
正如评论中所指出的,如果您想避免改变原始数组,可以使用 concat
,它将两个或多个数组连接在一起。您可以使用它在功能上将单个元素推送到现有数组的前面或后面;为此,您需要将新元素转换为单个元素数组:
const array = [3, 2, 1] const newFirstElement = 4 const newArray = [newFirstElement].concat(array) // [ 4, 3, 2, 1 ] console.log(newArray);
concat
还可以附加项目。 concat
的参数可以是任何类型;如果它们还不是数组,则它们被隐式包装在单元素数组中:
const array = [3, 2, 1] const newLastElement = 0 // 这两行是等价的: const newArray1 = array.concat(newLastElement) // [ 3, 2, 1, 0 ] const newArray2 = array.concat( [newLastElement]) // [ 3, 2, 1, 0 ] console.log(newArray1);控制台.log(newArray2);
https://i.stack.imgur.com/1pQk8.jpg
var a = [23, 45, 12, 67]; a.unshift(34);控制台.log(a); // [34, 23, 45, 12, 67]
[23, 45, 12, 67].unshift(34)
不起作用。数组必须首先保存在变量中,因为unshift
本身会返回一个值。
在 ES6 中,使用扩展运算符 ...:
演示
var arr = [23, 45, 12, 67]; arr = [34, ...arr]; // 结果 : [34,23, 45, 12, 67] console.log(arr)
concat
。
另一种方法是通过 concat
:
var arr = [1, 2, 3, 4, 5, 6, 7];控制台.log([0].concat(arr));
concat
和 unshift
之间的区别在于 concat
返回一个新数组。他们之间的表现可以找到here。
function fn_unshift() {
arr.unshift(0);
return arr;
}
function fn_concat_init() {
return [0].concat(arr)
}
这是测试结果:
https://i.stack.imgur.com/f5u3L.png
unshift
:25,510 ±3.18% 慢 99% concat
:2,436,894 ±3.39% 最快
快速备忘单:
术语 shift/unshift 和 push/pop 可能有点令人困惑,至少对于可能不熟悉 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 )
使用 ES6 destructuring(避免原始数组的突变):
const newArr = [item, ...oldArr]
没有变异
实际上,所有 unshift
/push
和 shift
/pop
mutate 源数组。
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+
通过上述方式,您可以添加到数组的开头/结尾而没有突变。
originArray
的末尾放置了一个 slice
函数,以防止它的可变性。
您有一个数组:var arr = [23, 45, 12, 67];
要将项目添加到开头,您需要使用 splice
:
var arr = [23, 45, 12, 67]; arr.splice(0, 0, 34) console.log(arr);
unshift
快 50%(但大多数情况下更具可读性)
备忘单将新元素添加到数组中
<强> 1。 Array#unshift
常量列表 = [23, 45, 12, 67]; list.unshift(34);控制台.log(列表); // [34, 23, 45, 12, 67];
<强> 2。 Array#splice
常量列表 = [23, 45, 12, 67]; list.splice(0, 0, 34);控制台.log(列表); // [34, 23, 45, 12, 67];
<强> 3。 ES6 spread...
常量列表 = [23, 45, 12, 67]; const newList = [34, ...list];控制台.log(newList); // [34, 23, 45, 12, 67];
<强> 4。 Array#concat
常量列表 = [23, 45, 12, 67]; const newList = [32].concat(list);控制台.log(newList); // [34, 23, 45, 12, 67];
注意:在每个示例中,您可以通过提供更多要插入的项目来预先添加多个项目。
如果您需要在数组的开头连续插入一个元素,使用 push
语句然后调用 reverse
会更快,而不是一直调用 unshift
。
基准测试: http://jsben.ch/kLIYf
unshift
在所有主要桌面浏览器(至少在此 Mac 上)都取得了全面胜利。
使用 splice
我们在开头插入一个元素到数组中:
arrName.splice( 0, 0, 'newName1' );
如果要将数组中的元素推送到数组的开头,请使用 <func>.apply(<this>, <Array of args>)
:
常量 arr = [1, 2]; arr.unshift.apply(arr, [3, 4]);控制台.log(arr); // [3, 4, 1, 2]
有几种方法可以实现这一点:
使用移位(可变)
常量数 = 1;常量 arr = [2, 3]; arr.unshift(num);控制台.log(arr);
使用 ES6 解构(不可变)
常量数 = 1;常量 arr = [2, 3]; const newArr = [num, ...arr];控制台.log(newArr);
使用 Array.prototype.concat(不可变)
常量数 = 1;常量 arr = [2, 3]; const newArr = [num].concat(arr);控制台.log(newArr);
让 arr = [5, 6]; // 使用 unshift arr.unshift(4); console.log('arr : ', arr); // 使用扩展运算符 arr = [3, ...arr]; console.log('arr : ', arr); // 使用 concat arr = [2].concat(arr); console.log('arr : ', arr); // 使用拼接 arr.splice(0, 0, 1) console.log('arr : ', arr);
concat
可能更可取,因为它会返回新数组。对于链接非常有用。[thingToInsertToFront].concat(originalArray).reduce(fn).reverse().map(fn)
等...如果您使用unshift
,则无法进行链接,因为您得到的只是长度。