在JavaScript中创建任意长度的零填充数组最有效的方法是什么?


当前回答

这里还有一个不错的选择http://www.2ality.com/2013/11/initializing-arrays.html

function fillArrayWithNumbers(n) {
  var arr = Array.apply(null, Array(n));
  return arr.map(function (x, i) { return i });
}

其他回答

我正在测试T.J.Crowder的出色答案,并提出了一个基于concat解决方案的递归合并方案,该方案在他的Chrome测试中表现出色(我没有测试其他浏览器)。

function makeRec(len, acc) {
    if (acc == null) acc = [];
    if (len <= 1) return acc;
    var b = makeRec(len >> 1, [0]);
    b = b.concat(b);
    if (len & 1) b = b.concat([0]);
    return b;
},

使用makeRec(29)调用该方法。

function makeArrayOf(value, length) {
  var arr = [], i = length;
  while (i--) {
    arr[i] = value;
  }
  return arr;
}

makeArrayOf(0, 5); // [0, 0, 0, 0, 0]

makeArrayOf('x', 3); // ['x', 'x', 'x']

注意while通常比in、forEach等更有效。

简言之

最快的解决方案:

let a = new Array(n); for (let i=0; i<n; ++i) a[i] = 0;

最短(方便)的解决方案(小阵列慢3倍,大阵列慢一点(Firefox上最慢))

Array(n).fill(0)

细节

今天2020.06.09我在浏览器Chrome 83.0、Firefox 77.0和Safari 13.1上对macOS High Sierra 10.13.6进行测试。我测试了两个测试用例的所选解决方案

小数组-有10个元素-您可以在这里执行测试大阵列-具有1M个元素-您可以在这里执行测试

结论

基于新Array(n)+for(n)的解决方案是小型阵列和大型阵列的最快解决方案(Chrome除外,但仍非常快),建议作为快速跨浏览器解决方案基于新Float32Array(n)(I)的解决方案返回非典型数组(例如,您不能在其上调用push(..)),因此我不会将其结果与其他解决方案进行比较-但是,对于所有浏览器上的大型数组,此解决方案的速度比其他解决方案快10-20倍基于for(L,M,N,O)的解决方案对于小型阵列来说是快速的基于填充(B,C)的解决方案在Chrome和Safari上速度很快,但在Firefox上对于大型阵列的速度却慢得惊人。它们对于小型阵列来说是中速的基于Array.apply(P)的解决方案为大型阵列抛出错误函数P(n){return Array.apply(null,Array(n)).map(Number.pr原型.valueOf,0);}尝试{P(1000000);}捕获(e){console.error(e.message);}

代码和示例

以下代码显示了测量中使用的解决方案

函数A(n){return[…new Array(n)].fill(0);}函数B(n){返回新数组(n).fill(0);}函数C(n){return数组(n).fill(0);}函数D(n){return Array.from({length:n},()=>0);}函数E(n){return[…new Array(n)].map(x=>0);}//类型为的数组函数F(n){return Array.from(新Int32Array(n));}函数G(n){return Array.from(new Float32Array(n));}函数H(n){return Array.from(new Float64Array(n));//需要比float32多2倍的内存}函数I(n){返回新的Float32Array(n);//这不是典型的阵列}函数J(n){return[].slice.apply(new Float32Array(n));}//基于函数K(n){设a=[];a.长度=n;设i=0;而(i<n){a[i]=0;i++;}返回a;}函数L(n){设a=[];对于(设i=0;i<n;i++)a[i]=0;返回a;}函数M(n){设a=[];对于(设i=0;i<n;i++)a.push(0);返回a;}函数N(N){设a=新数组(n);对于(设i=0;i<n;++i)a[i]=0;返回a;}函数O(n){设a=新数组(n);对于(设i=n;i-;)a[i]=0;返回a;}//其他函数P(n){return Array.apply(null,Array(n)).map(Number.pr原型.valueOf,0);}函数Q(n){return“0”.repeat(n).split(“”).map(parseFloat);}函数R(n){返回新数组(n+1).join(“0”).split(“”).map(parseFloat)}// ---------//测试// ---------[A、B、C、D、E、F、G、H、I、J、K、L、M、N、O、P、Q、R]。对于每个(F=>{设a=f(10);console.log(`${f.name}长度=${a.length},arr[0]=${a[0]},arr[9]=${a[9]}`)});此代码段仅显示使用过的代码

Chrome的示例结果:

const arr=数组.from({长度:10}).fill(0);控制台日志(arr)

使用对象表示法

var x = [];

零填充?喜欢

var x = [0,0,0,0,0,0];

填充了“undefined”。。。

var x = new Array(7);

带零的obj符号

var x = [];
for (var i = 0; i < 10; i++) x[i] = 0;

作为补充说明,如果修改Array的原型

var x = new Array();

and

var y = [];

将对原型进行修改

无论如何,我不会过分关注这个操作的效率或速度,你可能会做很多其他事情,这些事情比安装一个包含零的任意长度数组更浪费和昂贵。