协慌网

登录 贡献 社区

创建零填充 JavaScript 数组的最有效方法?

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

答案

ES6 引入了Array.prototype.fill 。可以这样使用:

new Array(len).fill(0);

不知道它是否很快,但我喜欢它,因为它简短而自描述。

它仍然不在 IE 中( 检查兼容性),但是有一个polyfill 可用

尽管这是旧线程,但我想在其中加 2 美分。不知道这有多慢 / 快,但这只是一个快速的班轮。这是我的工作:

如果我要预填数字:

Array.apply(null, Array(5)).map(Number.prototype.valueOf,0);
// [0, 0, 0, 0, 0]

如果我想预填一个字符串:

Array.apply(null, Array(3)).map(String.prototype.valueOf,"hi")
// ["hi", "hi", "hi"]

其他答案建议:

new Array(5+1).join('0').split('')
// ["0", "0", "0", "0", "0"]

但是,如果您想要 0(数字)而不是 “0”(字符串中的零),则可以执行以下操作:

new Array(5+1).join('0').split('').map(parseFloat)
// [0, 0, 0, 0, 0]

简而言之

最快的解决方案

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

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

Array(n).fill(0)


细节

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

结论

  • 基于new Array(n)+for (N)的解决方案是适用于小型阵列和大型阵列的最快解决方案(Chrome 除外,但在那里仍然非常快),因此建议将其作为快速跨浏览器解决方案
  • new Float32Array(n) (I)的解决方案返回了非典型数组(例如,您无法push(..) ),因此我不将其结果与其他解决方案进行比较 - 但是该解决方案的速度比其他解决方案快 10 到 20 倍适用于所有浏览器上的大型数组
  • 基于解决方案for (L,M,N,O)是快速对于小阵列
  • fill (B,C)的解决方案在 Chrome 和 Safari 上运行速度很快,但对于大型阵列,在 Firefox 上速度却最慢。对于中等大小的阵列,它们的速度中等
  • Array.apply (P)的解决方案对大数组引发错误
    function P(n) {
      return Array.apply(null, Array(n)).map(Number.prototype.valueOf,0);
    }
    
    
    try {
      P(1000000);
    } catch(e) { 
      console.error(e.message);
    }

在此处输入图片说明

代码和示例

以下代码介绍了测量中使用的解决方案

function A(n) {
  return [...new Array(n)].fill(0);
}

function B(n) {
  return new Array(n).fill(0);
}

function C(n) {
  return Array(n).fill(0);
}

function D(n) {
  return Array.from({length: n}, () => 0);
}

function E(n) {
  return [...new Array(n)].map(x => 0);
}

// arrays with type

function F(n) {
  return Array.from(new Int32Array(n));
}

function G(n) {
  return Array.from(new Float32Array(n));
}

function H(n) {
  return Array.from(new Float64Array(n)); // needs 2x more memory than float32
}

function I(n) {
  return new Float32Array(n); // this is not typical array
}

function J(n) {
  return [].slice.apply(new Float32Array(n));
}

// Based on for

function K(n) {
  let a = [];
  a.length = n;
  let i = 0;
  while (i < n) {
    a[i] = 0;
    i++;
  }
  return a;
}

function L(n) {
  let a=[]; for(let i=0; i<n; i++) a[i]=0;
  return a;
}

function M(n) {
  let a=[]; for(let i=0; i<n; i++) a.push(0);
  return a;
}

function N(n) {
  let a = new Array(n); for (let i=0; i<n; ++i) a[i] = 0;
  return a;
}

function O(n) {
  let a = new Array(n); for (let i=n; i--;) a[i] = 0;
  return a;
}

// other

function P(n) {
  return Array.apply(null, Array(n)).map(Number.prototype.valueOf,0);
}

function Q(n) {
  return "0".repeat( n ).split("").map( parseFloat );
}

function R(n) {
  return new Array(n+1).join('0').split('').map(parseFloat)
}


// ---------
// TEST
// ---------

[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R].forEach(f => {
  let a = f(10); 
  console.log(`${f.name} length=${a.length}, arr[0]=${a[0]}, arr[9]=${a[9]}`)
});
This snippets only present used codes

Chrome 的结果范例

在此处输入图片说明