如何建立一个包含1…N的数组

我正在寻找如下全部替代方案,以建立一个包含1到N的JavaScript数组,其中N仅在运行时才知道。 数组

var foo = [];

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

在我看来,应该有一种没有循环的方法。 浏览器


#1楼

若是您碰巧像我同样在您的应用程序中使用d3.js ,D3提供了一个帮助程序功能来帮助您执行此操做。 app

所以,要得到一个从0到4的数组,就像这样简单: dom

d3.range(5)
[0, 1, 2, 3, 4]

并按照您的要求从1到5得到一个数组: 函数

d3.range(1, 5+1)
[1, 2, 3, 4, 5]

查看本教程以获取更多信息。 this


#2楼

这多是生成数字数组的最快方法 spa

最短的 prototype

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

排队 code

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]

为何?

  1. while是最快的循环

  2. 直接设置比push更快

  3. []new Array(10)

  4. 简短...看第一个代码。 而后在这里查看全部其余功能。

若是你喜欢生活中不可缺乏

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

要么

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

#3楼

如下函数返回一个由数字填充的数组:

var createArrayOfNumbers = function (n) {
    return Array.apply(null, new Array(n)).map(function (empty, index) {
        return index;
    });
};

请注意,使用数组构造函数建立的数组包含孔,所以没法使用诸如map之类的数组函数遍历该数组。 所以,使用Array.apply函数。


#4楼

您能够这样作:

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

结果:[0、一、二、三、四、五、六、七、八、9]

或具备随机值:

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

结果:[0.708269490161910七、0.957222590921446七、0.858674854272976五、0.865384814329445四、0.00833987747319042七、0.991175662260502六、0.813342336099594八、0.837758846580982二、0.557757591595873二、0.16363654541783035]

说明

首先,请注意Number.call(undefined, N)等同于Number(N) ,后者仅返回N 稍后咱们将使用该事实。

Array.apply(null, [undefined, undefined, undefined])等同于Array(undefined, undefined, undefined) ,后者产生一个三元素数组,并将undefined分配给每一个元素。

您如何将其归纳为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.prototype.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) 。 所以, [undefined, undefined, …, undefined].map(Number.call, Number)会将每一个元素映射到(Number.call).call(Number, undefined, index, array) ,与Number.call(undefined, index, array)相同Number.call(undefined, index, array) ,如前所述,其计算结果为index 。 这样就完成了其元素与其索引相同的数组。

为何要麻烦Array.apply(null, {length: N})而不是Array(N) ? 毕竟,这两个表达式都将致使一个由N个元素组成的未定义元素数组。 区别在于,在前一个表达式中,每一个元素都显式设置为undefined,而在后一个表达式中,从未设置每一个元素。 根据.map()的文档:

仅对具备指定值的数组索引调用callback ; 对于已删除或从未分配值的索引,不会调用它。

所以, Array(N)不够; Array(N).map(Number.call, Number)将致使长度为N的未初始化数组。

兼容性

因为此技术依赖于ECMAScript 5中指定的Function.prototype.apply()行为,所以在ECMAScript 5以前的浏览器(例如Chrome 14和Internet Explorer 9)中将没法使用


#5楼

您可使用此:

new Array(/*any number which you want*/)
    .join().split(',')
    .map(function(item, index){ return ++index;})

例如

new Array(10)
    .join().split(',')
    .map(function(item, index){ return ++index;})

将建立如下数组:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
相关文章
相关标签/搜索