在 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 倍,大数组稍慢(在 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) 的解决方案对大数组抛出错误
代码和示例
下面的代码提供了测量中使用的解决方案
Chrome 的示例结果
如果我的回答有帮助你可以给我买杯咖啡
用预先计算的值填充数组的优雅方式
这是使用 ES6 的另一种方法,到目前为止没有人提到过:
> Array.from(Array(3), () => 0)
< [0, 0, 0]
它的工作原理是传递一个 map 函数作为 的第二个参数Array.from
。
在上面的例子中,第一个参数分配一个由 3 个位置填充的数组,undefined
然后 lambda 函数将每个位置映射到 value 0
。
虽然Array(len).fill(0)
较短,但如果您需要先进行一些计算来填充数组,它就不起作用(我知道这个问题没有要求它,但很多人最终在这里寻找这个)。
例如,如果您需要一个包含 10 个随机数的数组:
> Array.from(Array(10), () => Math.floor(10 * Math.random()))
< [3, 6, 8, 1, 9, 3, 0, 6, 7, 1]
它比等效的更简洁(和优雅):
const numbers = Array(10);
for (let i = 0; i < numbers.length; i++) {
numbers[i] = Math.round(10 * Math.random());
}
通过利用回调中提供的 index 参数,此方法还可用于生成数字序列:
> Array.from(Array(10), (d, i) => i)
< [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
奖励答案:使用字符串填充数组 repeat()
由于这个答案得到了很多关注,我也想展示这个很酷的技巧。虽然不如我的主要答案有用,但将介绍仍然不太为人所知但非常有用的 Stringrepeat()
方法。这是诀窍:
> "?".repeat(10).split("").map(() => Math.floor(10 * Math.random()))
< [5, 6, 3, 5, 0, 8, 2, 7, 4, 1]
很酷吧?repeat()
是一种非常有用的方法来创建一个字符串,该方法是将原始字符串重复一定次数。之后,split()
为我们创建一个数组,然后map()
将其输入到我们想要的值。分步分解:
> "?".repeat(10)
< "??????????"
> "?".repeat(10).split("")
< ["?", "?", "?", "?", "?", "?", "?", "?", "?", "?"]
> "?".repeat(10).split("").map(() => Math.floor(10 * Math.random()))
< [5, 6, 3, 5, 0, 8, 2, 7, 4, 1]