预先给数组赋值的最有效的方法

假设我有一个大小为N (其中N > 0 )的数组,是否有一个更有效的方法来预先考虑数组,而不需要O(N + 1)个步骤?

在代码中,基本上,我现在正在做的是

 function prependArray(value, oldArray) { var newArray = new Array(value); for(var i = 0; i < oldArray.length; ++i) { newArray.push(oldArray[i]); } return newArray; } 

我不确定更高效的大O,但肯定使用unshift方法更简洁:

 var a = [1, 2, 3, 4]; a.unshift(0); a; // => [0, 1, 2, 3, 4] 

[编辑]

这个jsPerf基准testing表明,至less在几个浏览器中,不移位的速度要快得多,而不pipe可能不同的big-O性能如果你可以在原地修改数组。 如果你真的不能改变原始数组,那么你会做类似下面的代码片段,这似乎没有比你的解决scheme明显更快:

 a.slice().unshift(0); // Use "slice" to avoid mutating "a". 

[编辑2]

为了完整性,可以使用下面的函数来代替OP的例子prependArray(...)来利用Array unshift(...)方法:

 function prepend(value, array) { var newArray = array.slice(); newArray.unshift(value); return newArray; } var x = [1, 2, 3]; var y = prepend(0, x); y; // => [0, 1, 2, 3]; x; // => [1, 2, 3]; 

如果您将数组预先放在另一个数组的前面,那么使用concat会更有效。 所以:

 var newArray = values.concat(oldArray); 

但这仍然是oldArray大小的O(N)。 不过,它比手动迭代oldArray效率更高。 另外,根据具体情况,这可能会对你有所帮助,因为如果你要预先设定很多值,最好先把它们放到一个数组中,然后在最后连接oldArray,而不是单独预先分配每个值。

在oldArray的大小上没有办法做得比O(N)好,因为数组存储在连续的内存中,第一个元素位于固定的位置。 如果要在第一个元素之前插入,则需要移动所有其他元素。 如果您需要解决这个问题,请执行@GWW所说的并使用链接列表或不同的数据结构。

如果你想预先安排数组(a1和数组a2),你可以使用下面的代码:

 var a1 = [1, 2]; var a2 = [3, 4]; Array.prototype.unshift.apply(a1, a2); console.log(a1); // => [3, 4, 1, 2] 

使用ES6,现在可以使用spread运算符来创build一个新的数组,并在原始元素之前插入新的元素。

 // Prepend a single item. const a = [1, 2, 3]; console.log([0, ...a]); 

如果你需要保留旧的数组,切割旧的数组,并将新的数值移到切片的开始位置。

 var oldA=[4,5,6]; newA=oldA.slice(0); newA.unshift(1,2,3) oldA+'\n'+newA /* returned value: 4,5,6 1,2,3,4,5,6 */ 

有特别的方法:

 a.unshift(value); 

但是如果你想在数组中添加几个元素,使用这种方法会更快一些:

 var a = [1, 2, 3], b = [4, 5]; function prependArray(a, b) { var args = b; args.unshift(0); args.unshift(0); Array.prototype.splice.apply(a, args); } prependArray(a, b); console.log(a); // -> [4, 5, 1, 2, 3]