我正在寻找以下方法的任何替代方法,以创建包含1到N的JavaScript数组,其中N仅在运行时已知。

var foo = [];

for (var i = 1; i <= N; i++) {
   foo.push(i);
}

对我来说,我觉得应该有一种不用循环的方法。


当前回答

填充Array的新方法是:

const array=[…array(5).keys()]console.log(数组)

结果将为:[0,1,2,3,4]

其他回答

Object.keys(Array.apply(0,Array(3))).map(Number)

返回[0,1,2]。与伊戈尔·舒宾(Igor Shubin)的出色回答非常相似,但略少了一些诡计(并且长了一个角色)。

说明:

数组(3)//[未定义×3]生成长度n=3的数组。不幸的是,这个阵列对我们几乎毫无用处,所以我们必须…Array.apply(0,Array(3))//[未定义,未定义,undefined]使数组可迭代。注意:null作为apply的第一个参数更常见,但0更短。Object.keys(Array.apply(0,Array(3)))//[“0”,“1”,“2”]然后获取数组的键(因为数组是数组的类型)。数组是带有键索引的对象。Object.keys(Array.apply(0,Array(3))).map(Number)//[0,1,2]并映射到键上,将字符串转换为数字。

使用不修改Number.prototype的生成器函数的可移植版本。

函数序列(最大值,步长=1){返回{[Symbol.iiterat]:函数*(){对于(设i=1;i<=max;i+=步长),得出i}}}console.log([…序列(10)])

以下是摘要(在控制台中运行):

// 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的方式非常方便(可以内联),速度快,功能更强大

基于高票答案和高票评论。

const range = (from, to) => [...Array(to + 1).keys()].slice(from);

// usage
let test = [];
test = range(5, 10);
console.log(test); // output: [ 5, 6, 7, 8, 9, 10 ]

我在寻找一个功能性的解决方案,最终得到了:

function numbers(min, max) {
  return Array(max-min+2).join().split(',').map(function(e, i) { return min+i; });
}

console.log(numbers(1, 9));

注意:join().split(',')将稀疏数组转换为连续数组。