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

var foo = [];

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

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


当前回答

有一个小功能,它允许使用像[1,2]。范围(3,4)->[1,2,3,4]也适用于负参数。享受

Array.prototype.range = function(from, to)
{
   var range = (!to)? from : Math.abs(to - from) + 1, increase = from < to;
   var tmp = Array.apply(this, {"length": range}).map(function()
      {
         return (increase)?from++ : from--;
      }, Number);

   return this.concat(tmp);
};

其他回答

可以使用Int8Array、Int16Array和Int32Array创建范围从1到n的数组,如下所示:

const zeroTo100 = new Int8Array(100).map((curr, index) => curr = index + 1);
/* Int8Array(100) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 
55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 
74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 
93, 94, 95, 96, 97, 98, 99, 100]

还可以使用以下类型化数组在数组中生成1到n个项。

Uint8Array、Uint16Array和Uint32ArrayBigInt64阵列Uint8约束阵列浮置阵列32、浮置阵列64

当然,除了数字之外,您无法在这些数组中放置任何东西,所以使用这个小快捷方式会带来风险。

此外,如果您只需要一个包含n个零的数组,那么只需执行以下操作:

const arr_100_0s = new Int8Array(100)

编辑:您可以使用它快速生成范围,如下所示:

function range(start, end) {
    const arr = new Int8Array(end - start + 1).map((curr, i) => curr + i + start);
    return arr;
}

range(15, 30); // Int8Array(16) [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]

不完全符合用户的要求,但与IMO高度相关。

只是另一个ES6版本。

通过使用Array.from第二个可选参数:

Array.from(arrayLike[,mapFn[,thisArg]])

我们可以从空数组(10)位置构建编号数组:

Array.from(Array(10), (_, i) => i)

var arr=数组.来自(数组(10),(_,i)=>i);文档.写入(arr);

我发现了这条旧线索,因为我自己也在想同样的问题,但我想这里没有一个答案比Kokodoko评论的原始示例更容易,哈哈!

我最终自己使用了这个方法:

var foo = [];
while (foo.length < N)
    foo.push( foo.length + 1 );

这至少比常规的for循环稍微快一点,而且希望不容易出错(尽管在计算上可能更昂贵)。

甚至可以做以下事情:

var foo= [];
while (foo.length < N)
    foo.push( foo.length%4 + 1 );

以按顺序将阵列填充1-4次。或者使用此方法用单个项填充数组,尽管我想在这种情况下,只使用array(N).fill(x)可能会更快。

您可以使用Es6中的阵列填充和映射;就像一些人在回答这个问题时建议的那样。以下是一些示例:

Example-One: Array(10).fill(0).map((e,i)=>i+1)

Result-One: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Example-Two: Array(100/10).fill(0).map((e,i)=>(i*10)+10)

Result-Two:[10, 20, 30, 40, 50, 60, 70, 80, 90, 100]

我更喜欢这样,因为我觉得这很简单。

在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"))