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

var foo = [];

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

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


当前回答

使用ES6的多种方式

使用扩展运算符(…)和键方法

[ ...Array(N).keys() ].map( i => i+1);

填充/贴图

Array(N).fill().map((_, i) => i+1);

排列自

Array.from(Array(N), (_, i) => i+1)

Array.from和{length:N}hack

Array.from({ length: N }, (_, i) => i+1)

关于广义形式的注记

通过将i+1更改为所需的表达式(例如i*2、-i、1+i*2和i%2等),上述所有形式都可以生成初始化为几乎任何所需值的数组。如果表达式可以用函数f表示,那么第一种形式就变得简单

[ ...Array(N).keys() ].map(f)

示例:

Array.from({length: 5}, (v, k) => k+1); 
// [1,2,3,4,5]

由于数组在每个位置都是用undefined初始化的,因此v的值将是undefineed

展示所有表格的示例

让演示=(N)=>{控制台日志([…数组(N).keys()].map((i)=>i+1),数组(N).fill().map((_,i)=>i+1),数组.from(数组(N),(_,i)=>i+1),Array.from({length:N},(_,i)=>i+1))}演示(5)

具有自定义初始化函数f的更通用示例,即。

[ ...Array(N).keys() ].map((i) => f(i))

甚至更简单

[ ...Array(N).keys() ].map(f)

让demo=(N,f)=>{控制台日志([…数组(N).keys()].map(f),数组(N).fill().map((_,i)=>f(i)),数组.from(数组(N),(_,i)=>f(i)),数组.从({长度:N},(_,i)=>f(i)))}演示(5,i=>2*i+1)

其他回答

对于小范围,切片是不错的。N仅在运行时已知,因此:

[0, 1, 2, 3, 4, 5].slice(0, N+1)

Fast

这个解决方案可能是最快的——它是由lodash_.range函数启发而来的(但我的更简单、更快)

设N=10,i=0,a=阵列(N);而(i<N)a[i++]=i;控制台日志(a);

与当前(2020.12.11)相比,基于while/for的现有答案的性能优势

内存在开始时由a=数组(N)分配一次使用了增加索引i++——看起来比减少索引i快30%左右——(可能是因为CPU缓存在正向上更快)

在此答案中,使用了20多种其他解决方案进行了速度测试

我没有看到任何基于递归函数的解决方案(我自己也从未编写过递归函数),所以这里是我的尝试。

注意array.push(something)返回数组的新长度:

(a=[]).push(a.push(a.push(0))) //  a = [0, 1, 2]

使用递归函数:

var a = (function f(s,e,a,n){return ((n?n:n=s)>e)?a:f(s,e,a?a:a=[],a.push(n)+s)})(start,end) // e.g., start = 1, end = 5

编辑:其他两种解决方案

var a = Object.keys(new Int8Array(6)).map(Number).slice(1)

and

var a = []
var i=setInterval(function(){a.length===5?clearInterval(i):a.push(a.length+1)}) 
function arrGen(n) {
  var a = Array(n)
  while (n--) a[n] = n
  return a
}
// arrGen(10) => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

尝试在Number的原型中添加迭代器。

Number.prototype[Symbol.iterator] = function *(){
  let i = 0;
  while(i < this) yield i++;
  return;
}

现在数字是可迭代的,只需将一个数字传递给Array.from

Array.from(10);//[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

或者任何其他需要迭代的地方,比如。。。循环。

for(const number of 10) console.log(number);//logs 0 through 9 sequentially

这有点复杂,但也很酷。