在JavaScript中创建任意长度的零填充数组最有效的方法是什么?
当前回答
您可以检查索引是否存在,以便向其追加+1。
这样你就不需要一个填零的数组了。
例子:
var current_year = new Date().getFullYear();
var ages_array = new Array();
for (var i in data) {
if(data[i]['BirthDate'] != null && data[i]['BirthDate'] != '0000-00-00'){
var birth = new Date(data[i]['BirthDate']);
var birth_year = birth.getFullYear();
var age = current_year - birth_year;
if(ages_array[age] == null){
ages_array[age] = 1;
}else{
ages_array[age] += 1;
}
}
}
console.log(ages_array);
其他回答
ES6引入了Array.prototype.fill。它可以这样使用:
new Array(len).fill(0);
不确定它是否很快,但我喜欢它,因为它很短,很自我描述。
它仍然不在IE中(检查兼容性),但有一个polyfill可用。
我正在测试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)调用该方法。
用预先计算的值填充数组的优雅方式
这里有另一种使用ES6的方法,到目前为止没有人提到:
> Array.from(Array(3), () => 0)
< [0, 0, 0]
它通过传递一个map函数作为Array.from的第二个参数来工作。
在上面的示例中,第一个参数分配一个由3个位置组成的数组,其中填充了未定义的值,然后lambda函数将每个位置映射到值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());
}
此方法还可用于通过利用回调中提供的索引参数生成数字序列:
> Array.from(Array(10), (d, i) => i)
< [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
额外答案:使用String repeat()填充数组
由于这个答案受到了很多关注,我也想展示一下这个很酷的技巧。虽然不如我的主要答案有用,但将介绍一个仍然不是很有名,但非常有用的Stringrepeat()方法。诀窍如下:
> "?".repeat(10).split("").map(() => Math.floor(10 * Math.random()))
< [5, 6, 3, 5, 0, 8, 2, 7, 4, 1]
酷吧?repeat()是创建字符串的一种非常有用的方法,该字符串将原始字符串重复一定次数。之后,split()为我们创建一个数组,然后将其映射()到所需的值。按步骤分解:
> "?".repeat(10)
< "??????????"
> "?".repeat(10).split("")
< ["?", "?", "?", "?", "?", "?", "?", "?", "?", "?"]
> "?".repeat(10).split("").map(() => Math.floor(10 * Math.random()))
< [5, 6, 3, 5, 0, 8, 2, 7, 4, 1]
在我的测试中,这是我电脑中最快的
1亿个元素需要大约350毫秒。
"0".repeat(100000000).split('');
对于相同数量的元素,map(()=>0)需要大约7000毫秒,这是一个巨大的差异
我知道这不是问题的目的,但这里有一个开箱即用的想法。为什么?我的CSci教授指出,用零来“净化”数据并没有什么神奇之处。因此,最有效的方法是根本不做!只有当数据需要为零作为初始条件(如某些求和)时才这样做——这通常不是大多数应用程序的情况。