我正在寻找以下方法的任何替代方法,以创建包含1到N的JavaScript数组,其中N仅在运行时已知。
var foo = [];
for (var i = 1; i <= N; i++) {
foo.push(i);
}
对我来说,我觉得应该有一种不用循环的方法。
我正在寻找以下方法的任何替代方法,以创建包含1到N的JavaScript数组,其中N仅在运行时已知。
var foo = [];
for (var i = 1; i <= N; i++) {
foo.push(i);
}
对我来说,我觉得应该有一种不用循环的方法。
当前回答
使用ES6标准中的新Array方法和=>函数语法(编写时仅限Firefox)。
通过用未定义的:
Array(N).fill().map((_, i) => i + 1);
Array.from将“孔”转换为未定义,因此Array.map按预期工作:
Array.from(Array(5)).map((_, i) => i + 1)
其他回答
嗯,简单但重要的问题。Functional JS在Array对象下肯定缺少一个通用的展开方法,因为我们可能需要创建一个数字项数组,不仅是简单的[1,2,3,…,111],而且是一个函数产生的序列,可能是x=>x*2而不是x=>x
目前,要执行这项工作,我们必须依赖Array.prototype.map()方法。然而,为了使用Array.prototype.map(),我们需要提前知道数组的大小。还是。。如果我们不知道大小,那么我们可以使用Array.prototype.reduce(),但Array.protocol.reduce)用于缩小(折叠)而不是展开正确。。?
显然,我们需要函数JS中的Array.unfold()工具。这是我们可以简单地自己实现的;
Array.unfold = function(p,f,t,s){
var res = [],
runner = v => p(v,res.length-1,res) ? [] : (res.push(f(v)),runner(t(v)), res);
return runner(s);
};
数组展开(p,f,t,v)采用4个参数。
p这是一个定义停止位置的函数。与许多数组函子一样,p函数接受3个参数。值、索引和当前生成的数组。它应返回布尔值。当它返回true时,递归迭代停止。f这是一个返回下一项函数值的函数。t这是一个函数,用于返回下一个参数,以便在下一个回合中提供给f。s是种子值,用于通过f计算索引0的舒适座椅。
因此,如果我们打算创建一个数组,其中包含一个像1,4,9,16,25…n^2这样的序列,我们可以简单地这样做。
Array.unfold=函数(p,f,t,s){var res=[],转轮=v=>p(v,res.length-1,res)?[]:(res.push(f(v)),runner(t(v),res);回流流道;};var myArr=数组展开((_,i)=>i>=9,x=>Math.pow(x,2),x=>x+1,1);console.log(myArr);
“_”.重复(5).拆分(“”).映射((_,i)=>i+1)将产生[1,2,3,4,5]
由于有很多好的答案,这可能也是一个选项,您也可以使用下面的创建一个函数,它将适用于任何数字组合
const start = 10;
const end = 30;
const difference = Math.abs(start-end);
const rangeArray = new Array(difference + 1).fill(undefined).map((val, key) => {
return start > end ? start - key : start + key;
})
从1开始:
[...Array(31).keys()].map(a=>a+1)
以下是摘要(在控制台中运行):
// setup:
var n = 10000000;
function* rangeIter(a, b) {
for (let i = a; i <= b; ++i) yield i;
}
function range(n) {
let a = []
for (; n--; a[n] = n);
return a;
}
function sequence(max, step = 1) {
return {
[Symbol.iterator]: function* () {
for (let i = 1; i <= max; i += step) yield i
}
}
}
var t0, t1, arr;
// tests
t0 = performance.now();
arr = Array.from({ length: n }, (a, i) => 1)
t1 = performance.now();
console.log("Array.from({ length: n }, (a, i) => 1) Took " + (t1 - t0) + " milliseconds.");
t0 = performance.now();
arr = range(n);
t1 = performance.now();
console.log("range(n) Took " + (t1 - t0) + " milliseconds.");
t0 = performance.now();
arr = Array.from(rangeIter(0, n));
t1 = performance.now();
console.log("Array.from(rangeIter(0, n)) Took " + (t1 - t0) + " milliseconds.");
t0 = performance.now();
arr = [...rangeIter(0, n)];
t1 = performance.now();
console.log("[...rangeIter(0, n)] Took " + (t1 - t0) + " milliseconds.");
t0 = performance.now();
arr = Array.from(sequence(n));
t1 = performance.now();
console.log("Array.from(sequence(n)) Took " + (t1 - t0) + " milliseconds.");
t0 = performance.now();
arr = [...sequence(n)];
t1 = performance.now();
console.log("[...sequence(n)] Took " + (t1 - t0) + " milliseconds.");
t0 = performance.now();
arr = Array(n).fill(0).map(Number.call, Number);
t1 = performance.now();
console.log("Array(n).fill(0).map(Number.call, Number) Took " + (t1 - t0) + " milliseconds.");
t0 = performance.now();
arr = Array.from(Array(n).keys());
t1 = performance.now();
console.log("Array.from(Array(n).keys()) Took " + (t1 - t0) + " milliseconds.");
t0 = performance.now();
arr = [...Array(n).keys()];
t1 = performance.now();
console.log("[...Array(n).keys()] Took " + (t1 - t0) + " milliseconds.");
最快的是Array(n).fill(0).map(Number.call,Number),第二个是[…Array(n).keys()]
但是。。。rangeIter的方式非常方便(可以内联),速度快,功能更强大