我正在寻找以下方法的任何替代方法,以创建包含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)

其他回答

我发现了这条旧线索,因为我自己也在想同样的问题,但我想这里没有一个答案比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)可能会更快。

获取n个介于最小值和最大值之间的随机数的数组(虽然不是唯一的)

function callItWhatYouWant(n, min, max) {
    return Array.apply(null, {length: n}).map(Function.call, function(){return Math.floor(Math.random()*(max-min+1)+min)})
}

为了好玩,我想借鉴伊恩·亨利的答案。

当然,var array=new array(N);将为您提供大小为N的数组,但键和值将相同。。。。然后,要将数组缩短为M大小,请使用array.length=M…但对于一些添加的功能,请尝试:

function range()
{
    // This function takes optional arguments:
    // start, end, increment
    //    start may be larger or smaller than end
    // Example:  range(null, null, 2);

    var array = []; // Create empty array

      // Get arguments or set default values:
    var start = (arguments[0] ? arguments[0] : 0);
    var end   = (arguments[1] ? arguments[1] : 9);
      // If start == end return array of size 1
    if (start == end) { array.push(start); return array; }
    var inc   = (arguments[2] ? Math.abs(arguments[2]) : 1);

    inc *= (start > end ? -1 : 1); // Figure out which direction to increment.

      // Loop ending condition depends on relative sizes of start and end
    for (var i = start; (start < end ? i <= end : i >= end) ; i += inc)
        array.push(i);

    return array;
}

var foo = range(1, -100, 8.5)

for(var i=0;i<foo.length;i++){
  document.write(foo[i] + ' is item: ' + (i+1) + ' of ' + foo.length + '<br/>'); 
}​

上述输出:

1是第1项,共12项-7.5为第2项,共12项-16是第3项,共12项-24.5为第4项,共12项-33是第5项,共12项-41.5是第6项,共12项-50是第7项,共12项-58.5为第8项,共12项-67是第9项,共12项-75.5为第10项,共12项-84是第11项,共12项-92.5是第12项,共12项

jsFiddle示例

此函数使用自动生成的参数数组。

该函数创建一个数组,该数组中的值以大小增量开始,以大小增量结束,其中

range(start, end, increment);

每个值都有一个默认值,增量的符号无关紧要,因为增量的方向取决于开始和结束的相对大小。

for(var i,a=[i=0];i<10;a[i++]=i);

a=[1、2、3、4、5、6、7、8、9、10]

Array(8).fill(0).map(Number.call, Number)

偷取Igors数字。可以使用技巧,但使用fill()稍微缩短。仅适用于ES6及以上版本。