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

var foo = [];

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

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


当前回答

试试这个

const foo = numberOfItems=> [...Array(numberOfItems).keys()].map(i => i+1);

其他回答

在ES6中:

Array.from({length: 1000}, (_, i) => i).slice(1);

或者更好(没有额外的变量_,也没有额外的切片调用):

Array.from({length:1000}, Number.call, i => i + 1)

或者,如果您的列表少于256个结果,您可以使用Uint8Array来获得稍快的结果(或者,您可以根据列表的长度使用其他Uint列表,例如Uint16的最大值为65535,或Uint32的最大值4294967295等。不过,正式地说,这些类型的数组只是在ES6中添加的)。例如:

Uint8Array.from({length:10}, Number.call, i => i + 1)

ES5:

Array.apply(0, {length: 1000}).map(function(){return arguments[1]+1});

或者,在ES5中,对于map函数(类似于上面ES6中Array.from函数的第二个参数),可以使用Number.call

Array.apply(0,{length:1000}).map(Number.call,Number).slice(1)

或者,如果你在这里也反对.sslice,你可以执行上面的ES5等效操作(来自ES6),比如:

Array.apply(0,{length:1000}).map(Number.call, Function("i","return i+1"))

在v8中填充数组的最快方法是:

[...Array(5)].map((_,i) => i);

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

嗯,简单但重要的问题。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);

使用递归的ES6解决方案。不同于所有其他解决方案

const range = (n, A = []) => (n === 1) ? [n, ...A] : range(n - 1, [n, ...A]);


console.log(range(5));

我能想出的最简洁的办法是:

[...''.padEnd(N)].map((_,i)=>i+1)