Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 将值前置到数组的最有效方法_Javascript_Arrays_Prepend - Fatal编程技术网

Javascript 将值前置到数组的最有效方法

Javascript 将值前置到数组的最有效方法,javascript,arrays,prepend,Javascript,Arrays,Prepend,假设我有一个大小为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;

假设我有一个大小为
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;
}
函数prependArray(值,oldArray){
var newArray=新数组(值);
对于(变量i=0;i
我不确定在big-O方面是否更有效,但肯定使用
取消移位
方法更简洁:

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

这表明
unshift
在至少两种浏览器中速度都相当快,如果您对修改阵列没有意见的话,不管big-O性能可能有什么不同。如果您确实无法对原始数组进行变异,那么您可以执行以下代码片段,这似乎不会比您的解决方案快多少:

a.slice().unshift(0); // Use "slice" to avoid mutating "a".
[编辑2]

为完整起见,可以使用以下函数代替OP的示例
prependArray(…)
,以利用数组
unshift(…)
方法:

函数前置(值,数组){
var newArray=array.slice();
newArray.unshift(值);
返回新数组;
}
var x=[1,2,3];
变量y=前置(0,x);
y、 //=>[0, 1, 2, 3];
x、 //=>[1, 2, 3];

有一种特殊的方法:

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]

如果要将一个数组前置到另一个数组的前面,只使用
concat
会更有效。因此:

var newArray = values.concat(oldArray);
但这仍然是旧数组大小的O(N)。不过,它比在oldArray上手动迭代更有效。此外,根据具体情况,它可能会对您有所帮助,因为如果您要预加许多值,最好先将它们放入一个数组中,然后在最后放入concat oldArray,而不是单独预加每个值


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

f您需要保留旧数组, 切片旧值并取消移动新值 到切片的开头

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
*/

如果要在数组(a1与数组a2)前加前缀,可以使用以下命令:

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

在ES6中,您现在可以使用创建一个新数组,将新元素插入到原始元素之前

//在单个项目前面加上前缀。
常数a=[1,2,3];

console.log([0,…a])我对不同的预结束方法进行了一些新的测试。
对于小型阵列(前置到位示例:

var A=[7,8,9]
变量B=[1,2,3]
A.取消移位(…B)

console.log(A)/[1,2,3,7,8,9]
调用
unshift
仅返回新数组的长度。 因此,为了在开头添加一个元素并返回一个新数组,我做了以下操作:

let newVal = 'someValue';
let array = ['hello', 'world'];
[ newVal ].concat(array);
或者简单地使用扩展运算符:

[ newVal, ...array ]
这样,原始阵列将保持不变。

const x=1
常量列表=[2,3,4]


const newList=[x].concat(list)/[1,2,3,4]
尽管我非常喜欢链表和指针,但我觉得必须有一种更有效的方法来使用原生JS数据types@samccone:是的,无视我的评论对不起,我以为你说的是Java:PJava、JavaScript、C或Python,不管是哪种语言:数组和链表之间的复杂性权衡是一样的d列表在JS中可能相当笨拙,因为它们没有内置类(与Java不同),但如果您真正想要的是O(1)插入时间,那么您确实需要一个链表。克隆它是一项要求吗?如果是克隆它的要求,那么取消移动是不合适的,因为它将变异原始数组而不会创建副本。哦,是的,我忘记了
unshift
。但是请注意a)变异oldArray,而
concat
不会(因此,哪一个更适合你取决于具体情况)和b)它只插入一个元素。哇,这要慢得多。正如我所说,它正在复制数组(同时也创建一个新的数组
[0]
),而unshift正在原地对其进行变异。但两者都应该是O(N)。也为该站点的链接欢呼——看起来非常方便。这对oneliner很好,因为concat返回数组,unshift返回新的长度No。。。unshift将添加数组作为第一个参数:var a=[4,5];a、 未移位([1,2,3]);console.log(a);//->[4,5,1,2,3]你说得对!您需要使用
Array.prototype.unshift.apply(a,b)
谁决定调用
prepend
unshift
”?@ScottStafford
unshift
听起来更适合这种数组操作(它或多或少地移动元素)
prepend
更适合于链表,在链表中,您可以按字面意思预先添加元素。unshift是shift的补充函数。称之为“prepend”是一个奇怪的选择。取消移动就是移动,就像推就是弹出。这个解决方案只有一个问题。unshift()是否返回其长度,而不是此答案中的数组
push
unshift
都包含
u
,而
pop
shift
没有。这应该从2017年起进行表决。它很简洁。通过使用spread,它将返回新的流,这有助于链接进一步的修改。这也是纯粹的(意味着a和b不受影响)你没有提到与取消移位相比所花费的时间。我打算用这个答案来呈现一种我认为更令人难忘、更简洁的替代语法。我会更新。@FrankTan:干杯:)+1回答得好!但为了确保你不会