预先给数组赋值的最有效的方法
假设我有一个大小为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]