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

var foo = [];

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

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


当前回答

ES6中还有另一种方法,使用Array.from,它接受两个参数,第一个是arrayLike(在本例中是具有长度属性的对象),第二个是映射函数(在本示例中,我们将项映射到其索引)

Array.from({length:10}, (v,i) => i)

它更短,可用于生成偶数等其他序列

Array.from({length:10}, (v,i) => i*2)

此外,这比大多数其他方式具有更好的性能,因为它只在阵列中循环一次。查看截图以进行一些比较

//打开开发控制台以查看结果计数=100000console.time(“来自对象”)for(设i=0;i<count;i++){range=Array.from({length:10},(v,i)=>i)}console.timeEnd(“来自对象”)console.time(“来自按键”)for(设i=0;i<count;i++){range=Array.from(Array(10).keys())}console.timeEnd(“来自按键”)console.time(“应用”)for(设i=0;i<count;i++){range=Array.apply(null,{length:10}).map(函数(元素,索引){return index;})}console.timeEnd(“应用”)

其他回答

这可能是生成数字数组的最快方法

最短的

var a=[],b=N;while(b--)a[b]=b+1;

内联

var arr=(function(a,b){while(a--)b[a]=a;return b})(10,[]);
//arr=[0,1,2,3,4,5,6,7,8,9]

如果您想从1开始

var arr=(function(a,b){while(a--)b[a]=a+1;return b})(10,[]);
//arr=[1,2,3,4,5,6,7,8,9,10]

想要功能吗?

function range(a,b,c){c=[];while(a--)c[a]=a+b;return c}; //length,start,placeholder
var arr=range(10,5);
//arr=[5,6,7,8,9,10,11,12,13,14]

WHY?

while是最快的循环直接设置比推送更快[]比新阵列(10)更快它很短。。。查看第一个代码。然后看看这里的所有其他函数。

如果你喜欢,就不能没有

for(var a=[],b=7;b>0;a[--b]=b+1); //a=[1,2,3,4,5,6,7]

or

for(var a=[],b=7;b--;a[b]=b+1); //a=[1,2,3,4,5,6,7]

如果我得到了你想要的,你需要一个数字数组1..n,以后可以循环使用。

如果这就是你所需要的,你能代替它吗?

var foo = new Array(45); // create an empty array with length 45

然后当你想使用它时…(例如,未优化)

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

例如,如果你不需要在数组中存储任何东西,你只需要一个长度合适的容器,你可以遍历它。。。这可能更容易。

请在此处查看实际操作:http://jsfiddle.net/3kcvm/

有一个小功能,它允许使用像[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);
};

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

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(',')将稀疏数组转换为连续数组。

您可以这样做:

var N = 10; 
Array.apply(null, {length: N}).map(Number.call, Number)

结果:[0,1,2,3,4,5,6,7,8,9]

或具有随机值:

Array.apply(null, {length: N}).map(Function.call, Math.random)

结果:[0.782694901619107,0.9572225909214467,0.8586748542729765,0.8653848143294454, 0.008339877473190427, 0.9911756622605026, 0.8133423360995948, 0.8377588465809822, 0.5577575915958732, 0.16363654541783035]

解释

首先,注意Number.call(undefined,N)等同于Number(N),它只返回N。我们稍后将使用这个事实。

Array.apply(null,[undefined,undefineed,undefinded])等同于Array(undefine,undefine,undefide),它生成一个三元素数组,并为每个元素分配undefine。

如何将其推广到N个元素?考虑一下Array()的工作原理,大致如下:

function Array() {
    if ( arguments.length == 1 &&
         'number' === typeof arguments[0] &&
         arguments[0] >= 0 && arguments &&
         arguments[0] < 1 << 32 ) {
        return [ … ];  // array of length arguments[0], generated by native code
    }
    var a = [];
    for (var i = 0; i < arguments.length; i++) {
        a.push(arguments[i]);
    }
    return a;
}

自ECMAScript 5以来,Function.pr原型.apply(thisArg,argsArray)也接受鸭子类型的类似数组的对象作为其第二个参数。如果我们调用Array.apply(null,{length:N}),那么它将执行

function Array() {
    var a = [];
    for (var i = 0; i < /* arguments.length = */ N; i++) {
        a.push(/* arguments[i] = */ undefined);
    }
    return a;
}

现在我们有一个N元素数组,每个元素都设置为undefined。当我们对其调用.map(callback,thisArg)时,每个元素都将被设置为callback.call(thisArg,element,index,array)的结果。因此,[未定义,未定义,…,未定义].map(Number.call,Number)会将每个元素映射到(Number.call).call(Number,undefined,index,array),这与Number.ccall(undefineed,index,array)相同,正如我们之前所观察到的,它的计算结果为index。这就完成了元素与其索引相同的数组。

为什么要解决Array.apply(null,{length:N})而不是Array(N)的问题?毕竟,这两个表达式都会产生一个未定义元素的N元素数组。不同之处在于,在前一个表达式中,每个元素都被显式设置为undefined,而在后一个表达式,每个元素从未被设置。根据.map()的文档:

回调仅对已赋值数组的索引调用;对于已删除或从未赋值的索引,不会调用它。

因此,Array(N)不足;数组(N).map(Number.call,Number)将导致长度为N的未初始化数组。

兼容性

由于该技术依赖于ECMAScript 5中指定的Function.protype.apply()的行为,因此它在之前的ECMAScript5浏览器(如Chrome 14和Internet Explorer 9)中不起作用。