创建一个包含1 ... N的JavaScript数组

God*_*ers 985 javascript arrays

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

var foo = [];

for (var i = 1; i <= N; i++) {
   foo.push(i);
}
Run Code Online (Sandbox Code Playgroud)

对我而言,感觉应该有一种没有循环的方法.

Nik*_*nen 998

在ES6中使用Array from()keys()方法.

Array.from(Array(10).keys())
//=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Run Code Online (Sandbox Code Playgroud)

使用扩展运算符的较短版本.

[...Array(10).keys()]
//=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Run Code Online (Sandbox Code Playgroud)

  • 呃什么!?为什么`map`当你可以简单地`切片'?`[...阵列(N + 1).keys()].片(1)` (76认同)
  • 只需注意,这将始终从0开始.需要将`map`链接到数组以调整值(`[... Array(10).keys()].map(x => x ++); `)从1开始 (55认同)
  • 或者不使用键和映射,只是将映射函数传递给`from``Array.from(Array(10),(e,i)=> i + 1)` (47认同)
  • 只需将`map(x => x ++)`更改为`map(x => ++ x)`,因为在返回值后会发生优先级递增:) (28认同)
  • 或者不要使用`keys`和只有1个map - >`Array.from(Array(10)).map((e,i)=> i + 1)` (17认同)
  • IE不支持Array.from。 (2认同)
  • [...Array(10).keys()] 在我看来是最短和最好的答案。如果我想要性能 ID,请使用 for 循环。否则 id 只需要一种方法来记住生成数字列表的简单方法 (2认同)
  • [...Array(11).keys()].splice(1) 创建一个从 1 到 10 的数字数组(与 0 到 9,如 [...Array(10).keys()] 所做的那样) ,来完成原来的问题。当然,用N+1代替11。 (2认同)

Igo*_*bin 832

你可以这样做:

var N = 10; 
Array.apply(null, {length: N}).map(Number.call, Number)
Run Code Online (Sandbox Code Playgroud)

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

或随机值:

Array.apply(null, {length: N}).map(Function.call, Math.random)
Run Code Online (Sandbox Code Playgroud)

结果:[0.7082694901619107,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, 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;
}
Run Code Online (Sandbox Code Playgroud)

从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;
}
Run Code Online (Sandbox Code Playgroud)

现在我们有一个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),这正如我们前面观察到的,计算结果为index.这样就完成了元素与索引相同的数组.

为什么要经历麻烦Array.apply(null, {length: N})而不仅仅是Array(N)?毕竟,两个表达式都会产生一个未定义元素的N元素数组.不同之处在于,在前一个表达式中,每个元素都显式设置为undefined,而在后者中,每个元素都从未设置过.根据以下文件.map():

callback仅对已分配值的数组的索引调用; 对于已删除的索引或从未分配过值的索引,不会调用它.

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

兼容性

由于此技术依赖Function.prototype.apply()于ECMAScript 5 中指定的行为,因此它不适用于ECM 14和Internet Explorer 9之类的ECMAScript 5之前的浏览器.

  • +1表示聪明,但请注意这是一个数量级SLOWER而不是原始循环:http://jsperf.com/array-magic-vs-for (61认同)
  • 这真的非常聪明(与滥用JS有关).在我看来,这里真正重要的见解是对未分配值的`map`的特殊性.另一个版本(可能稍微更清楚,虽然更长)是:`Array.apply(null,{length:N}).map(function(element,index){return index;})` (13认同)
  • 非常聪明 - 可能太过分了.利用`Function.prototype.call`的第一个参数是直接映射到'Array.prototype.map`的迭代器参数的`this`对象这一事实具有一定的亮度. (7认同)
  • @BenReich更好(就JS滥用级别而言):`Array.apply(null,new Array(N)).map(function(_,i){return i;})`或者,如果是es6和arrow函数,甚至更短:`Array.apply(null,new Array(N)).map((_,i)=> i)` (6认同)
  • 如果这返回一个从 1 开始的数组,它实际上会回答 OP 的问题 (2认同)
  • 它应该是`Array.apply(null, {length: N + 1}).map(Number.call, Number).slice(1)` (2认同)

Abd*_*UMI 369

ES6简单明了的方法:

Array.from({length: 5}, (v, k) => k+1); 
// [1,2,3,4,5]
Run Code Online (Sandbox Code Playgroud)

因此:

    Array.from({length: N}, (v, k) => k+1);  
   // [1,2,3,...,N]
Run Code Online (Sandbox Code Playgroud)

const range = (N) => Array.from({length: N}, (v, k) => k+1) ;

console.log(
  range(5)
)
Run Code Online (Sandbox Code Playgroud)

  • 最佳答案恕我直言.另请参见https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Array/from (27认同)
  • 对从0开始的数组使用k ++ (5认同)
  • 如果你想自增,不要用`k++`,用`++k`。 (3认同)
  • 请注意,IE中不支持Array.from,除非您正在填充它. (3认同)
  • 为了让 TS 编译器满意,请考虑用 lodash 替换未使用的参数: Array.from({ length: 5 }, (_, k) =&gt; k + 1); (3认同)

scu*_*ffe 328

如果我得到你想要的东西,你需要一组数字1..n,你可以在以后循环.

如果这就是您所需要的,那么您可以这样做吗?

var foo = new Array(45); // create an empty array with length 45
Run Code Online (Sandbox Code Playgroud)

然后当你想要使用它时...(未优化,仅举例)

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

例如,如果你不需要在数组中存储任何东西,你只需要一个可以迭代的正确长度的容器......这可能会更容易.

在这里看到它:http://jsfiddle.net/3kcvm/

  • @Godders:如果你正在寻找这个,你为什么需要一个阵列?一个简单的`var n = 45;`然后从`1..n`循环就行了. (124认同)
  • @scunliffe:请注意,`new Array(45);`不会"创建一个45元素数组"(与`[undefined,undefined,.. undefined]`的含义相同).它相反"创建长度为45的空数组"(`[undefined x 45]`),与`var foo = []相同; foo.length = 45;`.这就是为什么`forEach`和`map`在这种情况下不适用的原因. (61认同)
  • 我真的不明白为什么这个答案甚至有赞成...特别是当OP自己同意它在上面的几条评论中没有任何意义,因为他可能只做了`var n = 45;`. (20认同)
  • 给你留下深刻的印象,设法用尽我的意思来表达我的问题,你确实是正确的,因为反思所有我需要的是一系列数字,我可以稍后循环:)谢谢你的回答. (3认同)
  • @Godders - 要注意,如果要在创建长度为M后减小数组的大小,只需使用`foo.length = M` ---切断信息就会丢失.看到它在行动==> http://jsfiddle.net/ACMXp/ (3认同)
  • @casablanca:当然你是对的,不敢相信我在发布问题之前找不到简单的答案。哦,好吧,最后到了那里。谢谢! (2认同)
  • 请注意,由于新数组(数字)不存在索引,因此.forEach()将不起作用.在这种情况下,另一个答案可能更好. (2认同)
  • 这个"答案"是无意义的; foo = {length:45}做同样的事情.请参阅http://jsperf.com/array-magic-vs-for/11上的"我的10000",速度提高7倍. (2认同)

vol*_*ron 224

我知道你的问题是要求用数字填充数组,但我不确定你为什么要这样做.

阵列固有地管理它们的长度.当它们被遍历时,它们的索引可以保存在内存中并在那时被引用.如果需要知道随机索引,则indexOf可以使用该方法.


这说,根据您的需要,您可能只想声明一个特定大小的数组:

var foo = new Array(N);   // where N is a positive integer

/* this will create an array of size, N, primarily for memory allocation, 
   but does not create any defined values

   foo.length                                // size of Array
   foo[ Math.floor(foo.length/2) ] = 'value' // places value in the middle of the array
*/
Run Code Online (Sandbox Code Playgroud)


ES6

传播

利用spread operator(...)和keys方法,可以创建一个大小为N的临时数组来生成索引,然后创建一个可以分配给变量的新数组:

var foo = [ ...Array(N).keys() ];
Run Code Online (Sandbox Code Playgroud)

填充/地图

您可以先创建所需数组的大小,使用undefined填充它,然后使用创建新数组map,将每个元素设置为索引.

var foo = Array(N).fill().map((v,i)=>i);
Run Code Online (Sandbox Code Playgroud)

Array.from

这应该初始化为大小为N的长度并一次填充数组.

Array.from({ length: N }, (v, i) => i)
Run Code Online (Sandbox Code Playgroud)

  • 就像我说的,我需要用数字1到10填充一个下拉列表。有一个用例,我的用例。这就是我找到此页面的方式。因此,只需要手工构建一个数组就比我在这里看到的要简单。因此,我的要求不是OP的要求。但是我有我的答案。 (4认同)

Nat*_*ate 182

在ES6中,您可以:

Array(N).fill().map((e,i)=>i+1);

http://jsbin.com/molabiluwa/edit?js,console

编辑:更改Array(45)Array(N)自您更新问题以来.

console.log(
  Array(45).fill(0).map((e,i)=>i+1)
);
Run Code Online (Sandbox Code Playgroud)

  • 对于其他感兴趣的人来说,Array(N)和Array(N).fill()之间的差异很好地解释了[这里](http://stackoverflow.com/questions/35013777/difference-between-arrayn-and- arrayn填充) (11认同)
  • 我不明白为什么`.fill()`是必要的.我看到它是在我测试节点的repl时,但是因为`Array(1)[0] === undefined`,在`Array(1).fill(undefined)`make中对fill()的调用有什么不同? (8认同)
  • ```const gen = N => [...(function*(){let i = 0; while(i <N)yield i ++})()]``` (4认同)
  • +1因为它比整个讨厌的`.join.split`version更好_O _****但我仍然认为简陋的循环更好. (3认同)

Eva*_*van 105

使用非常流行的Underscore _.range方法

// _.range([start], stop, [step])

_.range(10); // => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
_.range(1, 11); // => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
_.range(0, 30, 5); // => [0, 5, 10, 15, 20, 25]
_.range(0, -10, -1); //  => [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
_.range(0); // => []
Run Code Online (Sandbox Code Playgroud)

  • https://github.com/jashkenas/underscore/blob/3699e39631cfaa99ca88dc279decb6ff57989413/underscore.js#L691 (5认同)

Ami*_*adi 74

简单地说,这对我有用:

[...Array(5)].map(...)
Run Code Online (Sandbox Code Playgroud)

  • [...数组(5)].map((x,i)=&gt;i) (9认同)
  • 优雅简约。 (2认同)

Ian*_*nry 63

function range(start, end) {
    var foo = [];
    for (var i = start; i <= end; i++) {
        foo.push(i);
    }
    return foo;
}
Run Code Online (Sandbox Code Playgroud)

然后叫

var foo = range(1, 5);
Run Code Online (Sandbox Code Playgroud)

在Javascript中没有内置的方法来执行此操作,但如果您需要多次执行此操作,则它是一个非常有效的实用程序函数.

编辑:在我看来,以下是一个更好的范围功能.也许只是因为我对LINQ有偏见,但我认为它在更多情况下更有用.你的旅费可能会改变.

function range(start, count) {
    if(arguments.length == 1) {
        count = start;
        start = 0;
    }

    var foo = [];
    for (var i = 0; i < count; i++) {
        foo.push(start + i);
    }
    return foo;
}
Run Code Online (Sandbox Code Playgroud)

  • `Array.range(1,5)`可能更合适,但写`[] .range(1,5)`有一些很酷的东西. (9认同)
  • 而是使它成为一个"Array"而不是"Array.prototype"的方法,因为没有理由(甚至可能被认为是相当愚蠢)在每个数组上都有这个方法. (8认同)
  • @pilau正如亚当斯所说,它看起来很奇怪.如果它在原型上,你可以说`foo = [1,2,3]; bar = foo.range(0,10);`.但那只是......令人困惑.`bar = Array.range(0,10)`更清晰明了.范围与实例无关,因此没有理由将其作为实例方法. (3认同)
  • 我喜欢这个.如果你想加倍努力,你可以将它声明为Array.prototype.range = function(start,end){...};.然后,您可以在任何Array对象上调用range(x,y). (2认同)

аle*_*kyі 53

填写Arrayv8 的最快方法是:

[...Array(5)].map((_,i) => i);
Run Code Online (Sandbox Code Playgroud)

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


blu*_*yke 47

这个问题有很多复杂的答案,但是很简单:

[...Array(255).keys()].map(x => x + 1)
Run Code Online (Sandbox Code Playgroud)

另外,尽管上面的内容简短(简洁),但我认为下面的内容要快一些(最大长度为:

127,Int8,

255,Uint8,

32,767,Int16,

65,535,Uint16,

2,147,483,647,Int32,

4,294,967,295,Uint32。

(基于最大整数值),还有更多关于Typed Arrays的信息

(new Uint8Array(255)).map(($,i) => i + 1);
Run Code Online (Sandbox Code Playgroud)

尽管此解决方案也不是很理想,但是它创建了两个数组,并使用了额外的变量声明“ $”(不确定使用此方法解决该问题的任何方法)。我认为以下解决方案是绝对最快的方法:

for(var i = 0, arr = new Uint8Array(255); i < arr.length; i++) arr[i] = i + 1;
Run Code Online (Sandbox Code Playgroud)

在执行此语句后,您可以随时在当前作用域中简单地使用变量“ arr”。

如果您想用它做一个简单的功能(通过一些基本的验证):

[...Array(255).keys()].map(x => x + 1)
Run Code Online (Sandbox Code Playgroud)


因此,借助上述功能,上述超慢的“简单单缸”将变得超快甚至更短:

range(1,14000);
Run Code Online (Sandbox Code Playgroud)


nkt*_*ssh 43

你可以用这个:

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

例如

new Array(10)
    .join().split(',')
    .map(function(item, index){ return ++index;})
Run Code Online (Sandbox Code Playgroud)

将创建以下数组:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Run Code Online (Sandbox Code Playgroud)

  • 这是一个有趣的解决方案,但它完全不切实际 - 必须解析数组**3次**(一次"加入",一次"拆分",一次是你真正想做的事情)并不好 - 我知道他们似乎因某种原因失宠了,但简单地使用一个好的老式**循环**会好得多! (3认同)

Mo.*_*Mo. 41

空数组且数组中只有数字的解决方案

const arrayOne = new Array(10);
console.log(arrayOne);

const arrayTwo = [...Array(10).keys()];
console.log(arrayTwo);

var arrayThree = Array.from(Array(10).keys());
console.log(arrayThree);

const arrayStartWithOne = Array.from(Array(10).keys(), item => item + 1);
console.log(arrayStartWithOne)
Run Code Online (Sandbox Code Playgroud)


Tyl*_*ick 39

如果您碰巧在我的应用程序中使用d3.js,D3会提供一个辅助函数来为您执行此操作.

所以要从0到4获得一个数组,它就像:

d3.range(5)
[0, 1, 2, 3, 4]
Run Code Online (Sandbox Code Playgroud)

并按照您的要求获取1到5之间的数组:

d3.range(1, 5+1)
[1, 2, 3, 4, 5]
Run Code Online (Sandbox Code Playgroud)

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


coc*_*cco 39

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

最短

var a=[],b=N;while(b--)a[b]=b+1;
Run Code Online (Sandbox Code Playgroud)

排队

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

如果你想从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]
Run Code Online (Sandbox Code Playgroud)

想要一个功能?

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]
Run Code Online (Sandbox Code Playgroud)

为什么?

  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]
Run Code Online (Sandbox Code Playgroud)

要么

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

  • 最好用基准来支持这些声明.试试http://jsperf.com. (6认同)
  • @ cocco-*虽然*不总是**比其他循环快**.在某些浏览器中,递减while循环比for循环要慢得多,你不能像这样对javascript性能做一般性陈述,因为有太多不同优化的实现.但是,总的来说,我喜欢你的方法.;-) (5认同)
  • 仅供参考:正如John Reisig几年前首次发表的那样 - 在某些平台上(意思是窗口:P),时间每16毫秒就被送到浏览器一次.在多任务环境中测量执行时间还存在其他问题.jsperf.com已经实施了运行测试,以便它们在统计上是正确的.运行`console.time()`来获得直觉是可以的,但是为了证明,你需要jsperf.com它会向你显示来自其他人的跨浏览器结果(不同的硬件等) (4认同)
  • @cocco这是不正确的:`var a = [],b = N;而(b - ){a [b] = a + 1};` (3认同)
  • 大声笑jsperf ...请马特,因为你不喜欢我的回答停止低估我的其他人... http://stackoverflow.com/a/18344296/2450730 ...使用console.time()或如何调用它. ..不是jsperf. (2认同)

小智 39

ES6这样就可以了:

[...Array(12).keys()]
Run Code Online (Sandbox Code Playgroud)

看看结果:

[...Array(12).keys()].map(number => console.log(number))
Run Code Online (Sandbox Code Playgroud)

  • 实际上,他们要求1..N,而不是0..N-1 (5认同)
  • 几年前已经给出了`.keys()`答案(/sf/answers/2334682311/),并且有500多个投票。您的答案有什么好处? (2认同)

Vla*_*den 38

使用ES2015/ES6扩展运算符

[...Array(10)].map((_, i) => i + 1)
Run Code Online (Sandbox Code Playgroud)

console.log([...Array(10)].map((_, i) => i + 1))
Run Code Online (Sandbox Code Playgroud)

  • `i + 1`比`++ i`更有意义. (6认同)

Hon*_*iao 30

如果您使用的是lodash,则可以使用_.range:

_.range([start=0], end, [step=1])

创建从开始到结束但不包括结束的数字数组(正数和/或负数).如果指定了没有结束或步骤的负启动,则使用-1的步长.如果未指定end,则将其设置为以start开始,然后设置为0.

例子:

_.range(4);
// ? [0, 1, 2, 3]

_.range(-4);
// ? [0, -1, -2, -3]

_.range(1, 5);
// ? [1, 2, 3, 4]

_.range(0, 20, 5);
// ? [0, 5, 10, 15]

_.range(0, -4, -1);
// ? [0, -1, -2, -3]

_.range(1, 4, 0);
// ? [1, 1, 1]

_.range(0);
// ? []
Run Code Online (Sandbox Code Playgroud)


аle*_*kyі 30

新的填充方式Array是:

const array = [...Array(5).keys()]
console.log(array)
Run Code Online (Sandbox Code Playgroud)

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


Kam*_*ski 27

表现

今天 2020.12.11 我在 Chrome v87、Safari v13.1.2 和 Firefox v83 上对 MacOs HighSierra 10.13.6 进行测试,以获取选定的解决方案。

结果

适用于所有浏览器

  • 解决方案O(基于while)最快(除了 Firefox for big N - 但它在那里很快)
  • 解决方案 T 在 Firefox for big N 上最快
  • 解决方案 M,P 对于小 N 是快速的
  • 解决方案 V (lodash) 对于大 N 来说很快
  • 解决方案 W,X 对于小 N 很慢
  • 解决方案 F 很慢

在此处输入图片说明

细节

我执行 2 个测试用例:

  • 对于小 N = 10 - 你可以在这里运行
  • 对于大 N = 1000000 - 你可以在这里运行

下面的片段展示了所有经过测试的解决方案A B C D E F G H I J K L M N O P Q R S T U V W X

function A(N) {
  return Array.from({length: N}, (_, i) => i + 1)
}

function B(N) {
  return Array(N).fill().map((_, i) => i+1);
}

function C(N) {
  return Array(N).join().split(',').map((_, i) => i+1 );
}

function D(N) {
  return Array.from(Array(N), (_, i) => i+1)
}

function E(N) {
  return Array.from({ length: N }, (_, i) => i+1)
}

function F(N) {
  return Array.from({length:N}, Number.call, i => i + 1)
}

function G(N) {
  return (Array(N)+'').split(',').map((_,i)=> i+1)
}

function H(N) {
  return [ ...Array(N).keys() ].map( i => i+1);
}

function I(N) {
  return [...Array(N).keys()].map(x => x + 1);
}

function J(N) {
  return [...Array(N+1).keys()].slice(1)
}

function K(N) {
  return [...Array(N).keys()].map(x => ++x);
}

function L(N) {
  let arr; (arr=[ ...Array(N+1).keys() ]).shift();
  return arr;
}

function M(N) {
  var arr = [];
  var i = 0;

  while (N--) arr.push(++i);

  return arr; 
}

function N(N) {
  var a=[],b=N;while(b--)a[b]=b+1;
  return a;
}

function O(N) {
  var a=Array(N),b=0;
  while(b<N) a[b++]=b;
  return a;
}

function P(N) {
  var foo = [];
  for (var i = 1; i <= N; i++) foo.push(i);
  return foo;
}

function Q(N) {
  for(var a=[],b=N;b--;a[b]=b+1);
  return a;
}

function R(N) {
  for(var i,a=[i=0];i<N;a[i++]=i);
  return a;
}

function S(N) {
    let foo,x;
    for(foo=[x=N]; x; foo[x-1]=x--);
  return foo;
}

function T(N) {
  return new Uint8Array(N).map((item, i) => i + 1);
}

function U(N) {
  return '_'.repeat(5).split('').map((_, i) => i + 1);
}

function V(N) {
  return _.range(1, N+1);
}

function W(N) {
  return [...(function*(){let i=0;while(i<N)yield ++i})()]
}

function X(N) {
  function sequence(max, step = 1) {
    return {
      [Symbol.iterator]: function* () {
        for (let i = 1; i <= max; i += step) yield i
      }
    }
  }

  return [...sequence(N)];
}


[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X].forEach(f=> {
  console.log(`${f.name} ${f(5)}`);
})
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js" integrity="sha512-90vH1Z83AJY9DmlWa8WkjkV79yfS2n2Oxhsi2dZbIv0nC4E6m5AbH8Nh156kkM7JePmqD6tcZsfad1ueoaovww==" crossorigin="anonymous"> </script>
  
This shippet only presents functions used in performance tests - it not perform tests itself!
Run Code Online (Sandbox Code Playgroud)

以下是 chrome 的示例结果

在此处输入图片说明


sap*_*apy 26

最终总结报告.. Drrruummm Rolll -

这是在不使用ES6的情况下生成大小为N的数组(此处为10)的最短代码.Cocco上面的版本很接近但不是最短的.

(function(n){for(a=[];n--;a[n]=n+1);return a})(10)
Run Code Online (Sandbox Code Playgroud)

但是,这个Code高尔夫球的无可争议的赢家(用最少的源代码来解决特定问题的比赛)是Niko Ruotsalainen.使用Array Constructor和ES6 spread运算符.(大多数ES6语法都是有效的typeScript,但以下不是.所以在使用它时要明智)

[...Array(10).keys()]
Run Code Online (Sandbox Code Playgroud)


nki*_*tku 26

/sf/answers/3470413201/

与达美

对于 JavaScript

最小单线
[...Array(N)].map((v, i) => from + i * step);
Run Code Online (Sandbox Code Playgroud)

示例和其他替代方案

Array.from(Array(10).keys()).map(i => 4 + i * 2);
//=> [4, 6, 8, 10, 12, 14, 16, 18, 20, 22]

[...Array(10).keys()].map(i => 4 + i * -2);
//=> [4, 2, 0, -2, -4, -6, -8, -10, -12, -14]

Array(10).fill(0).map((v, i) => 4 + i * 2);
//=> [4, 6, 8, 10, 12, 14, 16, 18, 20, 22]

Array(10).fill().map((v, i) => 4 + i * -2);
//=> [4, 2, 0, -2, -4, -6, -8, -10, -12, -14]

[...Array(10)].map((v, i) => 4 + i * 2);
//=> [4, 6, 8, 10, 12, 14, 16, 18, 20, 22]
Run Code Online (Sandbox Code Playgroud) 范围函数
const range = (from, to, step) =>
  [...Array(Math.floor((to - from) / step) + 1)].map((_, i) => from + i * step);

range(0, 9, 2);
//=> [0, 2, 4, 6, 8]

// can also assign range function as static method in Array class (but not recommended )
Array.range = (from, to, step) =>
  [...Array(Math.floor((to - from) / step) + 1)].map((_, i) => from + i * step);

Array.range(2, 10, 2);
//=> [2, 4, 6, 8, 10]

Array.range(0, 10, 1);
//=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Array.range(2, 10, -1);
//=> []

Array.range(3, 0, -1);
//=> [3, 2, 1, 0]
Run Code Online (Sandbox Code Playgroud) 作为迭代器
class Range {
  constructor(total = 0, step = 1, from = 0) {
    this[Symbol.iterator] = function* () {
      for (let i = 0; i < total; yield from + i++ * step) {}
    };
  }
}

[...new Range(5)]; // Five Elements
//=> [0, 1, 2, 3, 4]
[...new Range(5, 2)]; // Five Elements With Step 2
//=> [0, 2, 4, 6, 8]
[...new Range(5, -2, 10)]; // Five Elements With Step -2 From 10
//=>[10, 8, 6, 4, 2]
[...new Range(5, -2, -10)]; // Five Elements With Step -2 From -10
//=> [-10, -12, -14, -16, -18]

// Also works with for..of loop
for (i of new Range(5, -2, 10)) console.log(i);
// 10 8 6 4 2
Run Code Online (Sandbox Code Playgroud) 仅作为发电机
const Range = function* (total = 0, step = 1, from = 0) {
  for (let i = 0; i < total; yield from + i++ * step) {}
};

Array.from(Range(5, -2, -10));
//=> [-10, -12, -14, -16, -18]

[...Range(5, -2, -10)]; // Five Elements With Step -2 From -10
//=> [-10, -12, -14, -16, -18]

// Also works with for..of loop
for (i of Range(5, -2, 10)) console.log(i);
// 10 8 6 4 2

// Lazy loaded way
const number0toInf = Range(Infinity);
number0toInf.next().value;
//=> 0
number0toInf.next().value;
//=> 1
// ...
Run Code Online (Sandbox Code Playgroud)

从到与步骤/增量

使用迭代器
class Range2 {
  constructor(to = 0, step = 1, from = 0) {
    this[Symbol.iterator] = function* () {
      let i = 0,
        length = Math.floor((to - from) / step) + 1;
      while (i < length) yield from + i++ * step;
    };
  }
}
[...new Range2(5)]; // First 5 Whole Numbers
//=> [0, 1, 2, 3, 4, 5]

[...new Range2(5, 2)]; // From 0 to 5 with step 2
//=> [0, 2, 4]

[...new Range2(5, -2, 10)]; // From 10 to 5 with step -2
//=> [10, 8, 6]
Run Code Online (Sandbox Code Playgroud) 使用发电机
const Range2 = function* (to = 0, step = 1, from = 0) {
  let i = 0,
    length = Math.floor((to - from) / step) + 1;
  while (i < length) yield from + i++ * step;
};

[...Range2(5, -2, 10)]; // From 10 to 5 with step -2
//=> [10, 8, 6]

let even4to10 = Range2(10, 2, 4);
even4to10.next().value;
//=> 4
even4to10.next().value;
//=> 6
even4to10.next().value;
//=> 8
even4to10.next().value;
//=> 10
even4to10.next().value;
//=> undefined
Run Code Online (Sandbox Code Playgroud)

对于打字稿

class _Array<T> extends Array<T> {
  static range(from: number, to: number, step: number): number[] {
    return Array.from(Array(Math.floor((to - from) / step) + 1)).map(
      (v, k) => from + k * step
    );
  }
}
_Array.range(0, 9, 1);
Run Code Online (Sandbox Code Playgroud)

  • 这是我在堆栈溢出中见过的最难的弹性 (2认同)

Ant*_*nio 24

非常简单且容易生成 1 - N

const [, ...result] = Array(11).keys();

console.log('Result:', result);
Run Code Online (Sandbox Code Playgroud)


小智 21

使用ES6,您可以执行以下操作:

// `n` is the size you want to initialize your array
// `null` is what the array will be filled with (can be any other value)
Array(n).fill(null)
Run Code Online (Sandbox Code Playgroud)


Gaa*_*far 19

在ES6中还有另一种方法,使用Array.from获取2个参数,第一个是arrayLike(在本例中是一个带有length属性的对象),第二个是映射函数(在这种情况下,我们将项目映射到其索引)

Array.from({length:10}, (v,i) => i)
Run Code Online (Sandbox Code Playgroud)

这个更短,可以用于其他序列,如生成偶数

Array.from({length:10}, (v,i) => i*2)
Run Code Online (Sandbox Code Playgroud)

此外,它具有比大多数其他方式更好的性能,因为它只在数组中循环一次.检查snippit进行一些比较

// open the dev console to see results

count = 100000

console.time("from object")
for (let i = 0; i<count; i++) {
  range = Array.from({length:10}, (v,i) => i )
}
console.timeEnd("from object")

console.time("from keys")
for (let i =0; i<count; i++) {
  range = Array.from(Array(10).keys())
}
console.timeEnd("from keys")

console.time("apply")
for (let i = 0; i<count; i++) {
  range = Array.apply(null, { length: 10 }).map(function(element, index) { return index; })
}
console.timeEnd("apply")
Run Code Online (Sandbox Code Playgroud)


blu*_*yke 19

在 ES6 中:

Array.from({length: 1000}, (_, i) => i).slice(1);
Run Code Online (Sandbox Code Playgroud)

或者更好(没有额外的变量 _ 并且没有额外的slice调用):

Array.from({length:1000}, Number.call, i => i + 1)
Run Code Online (Sandbox Code Playgroud)

或者对于稍微快一点的结果,您可以使用 Uint8Array,如果您的列表少于 256 个结果(或者您可以使用其他 Uint 列表,具体取决于列表的长度,例如 Uint16 表示最大数量为 65535,或 Uint32 表示最大数量4294967295 等。正式地说,这些类型化数组仅在 ES6 中添加)。例如:

Uint8Array.from({length:10}, Number.call, i => i + 1)
Run Code Online (Sandbox Code Playgroud)

ES5:

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

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

Array.apply(0,{length:1000}).map(Number.call,Number).slice(1)
Run Code Online (Sandbox Code Playgroud)

或者,如果你也反对.slice这里,你可以做上面的 ES5 等价物(来自 ES6),比如:

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


аle*_*kyі 16

Array(...Array(9)).map((_, i) => i);

console.log(Array(...Array(9)).map((_, i) => i))
Run Code Online (Sandbox Code Playgroud)


Kam*_*ski 16

快速地

这个解决方案可能是最快的,它的灵感来自 lodash _.range 函数(但我的更简单更快)

let N=10, i=0, a=Array(N);

while(i<N) a[i++]=i;



console.log(a);
Run Code Online (Sandbox Code Playgroud)

与当前 (2020.12.11) 现有答案相比的性能优势 while/for

  • 内存在开始时分配一次 a=Array(N)
  • 使用增加索引i++- 看起来比减少索引快约 30% i--(可能是因为 CPU 缓存在向前方向上更快)

此答案中进行了 20 多种其他解决方案的速度测试


szy*_*zet 15

使用=>ES6标准中的新Array方法和函数语法(在撰写本文时仅使用Firefox).

通过填充孔undefined:

Array(N).fill().map((_, i) => i + 1);
Run Code Online (Sandbox Code Playgroud)

Array.from将"洞"变成undefined如此Array.map按预期工作:

Array.from(Array(5)).map((_, i) => i + 1)
Run Code Online (Sandbox Code Playgroud)

  • 同样,您也可以在ES6中执行以下操作:`Array.from({length:N},(v,k)=> k)`. (7认同)

小智 13

for(var i,a=[i=0];i<10;a[i++]=i);
Run Code Online (Sandbox Code Playgroud)

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


Mir*_*ili 12

感谢@NikoRuotsalainen回答。我在我的实用程序中写了这个:

const range = ({from = 0, to, step = 1, length = Math.ceil((to - from) / step)}) => 
  Array.from({length}, (_, i) => from + i * step)
Run Code Online (Sandbox Code Playgroud)

例子:

const range = ({from = 0, to, step = 1, length = Math.ceil((to - from) / step)}) => 
  Array.from({length}, (_, i) => from + i * step)

console.log(
  range({length: 5}), // [0, 1, 2, 3, 4]
  range({to: 5}),    // [0, 1, 2, 3, 4]
  range({from: 2, to: 5}),    // [2, 3, 4] (inclusive `from`, exclusive `to`)
  range({from: 2, length: 4}), // [2, 3, 4, 5]
  range({from: 1, to: 5, step: 2}), // [1, 3]
  range({from: 1, to: 6, step: 2}), // [1, 3, 5]
)
Run Code Online (Sandbox Code Playgroud)


Mat*_* Lo 9

比字符串变体简单一点:

// create range by N
Array(N).join(0).split(0);

// create a range starting with 0 as the value
Array(7).join(0).split(0).map((v, i) => i + 1) // [1, 2, 3, 4, 5, 6, 7]
Run Code Online (Sandbox Code Playgroud)

更新(1/4/2018):已更新以解决确切的OP问题.谢谢@lessless打电话给我!


Rob*_*bin 9

似乎目前在这个相当完整的答案列表中没有的唯一风味是以发电机为特色; 所以补救一下:

const gen = N => [...(function*(){let i=0;while(i<N)yield i++})()]
Run Code Online (Sandbox Code Playgroud)

因此可以使用:

gen(4) // [0,1,2,3]
Run Code Online (Sandbox Code Playgroud)

关于这一点的好处是你不必只是增加......为了从@ igor-shubin给出的答案中获取灵感,你可以很容易地创建一个random数组:

const gen = N => [...(function*(){let i=0;
  while(i++<N) yield Math.random()
})()]
Run Code Online (Sandbox Code Playgroud)

和而不是一些冗长的操作上昂贵的,如:

const slow = N => new Array(N).join().split(',').map((e,i)=>i*5)
// [0,5,10,15,...]
Run Code Online (Sandbox Code Playgroud)

你可以这样做:

const fast = N => [...(function*(){let i=0;while(i++<N)yield i*5})()]
Run Code Online (Sandbox Code Playgroud)


yck*_*art 9

使用不修改的生成器函数的可迭代版本Number.prototype.

function sequence(max, step = 1) {
  return {
    [Symbol.iterator]: function* () {
      for (let i = 1; i <= max; i += step) yield i
    }
  }
}

console.log([...sequence(10)])
Run Code Online (Sandbox Code Playgroud)


Tim*_*ses 9

Array.from({ length: (stop - start) / step + 1}, (_, i) => start + (i * step));
Run Code Online (Sandbox Code Playgroud)

来源:https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from


Ale*_*shy 9

我会这样做 ...Array(N).keys()

var foo = [...Array(5).keys()].map(foo => foo + 1)

console.log(foo)
Run Code Online (Sandbox Code Playgroud)


Bel*_*mir 9

你可以这样做:

var arr = Array.from(Array(10).keys())
arr.shift()
console.log(arr)
Run Code Online (Sandbox Code Playgroud)


Geo*_*lah 8

使用ES6

const generateArray = n => [...Array(n)].map((_, index) => index + 1);
Run Code Online (Sandbox Code Playgroud)


zur*_*fyx 8

只是另一个ES6版本.

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

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

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

Array.from(Array(10), (_, i) => i)
Run Code Online (Sandbox Code Playgroud)

var arr = Array.from(Array(10), (_, i) => i);
document.write(arr);
Run Code Online (Sandbox Code Playgroud)


Zac*_*ner 7

试试这个:

var foo = [1, 2, 3, 4, 5];
Run Code Online (Sandbox Code Playgroud)

如果您使用的是CoffeeScript,则可以通过执行以下操作来创建范围:

var foo = [1..5]; 
Run Code Online (Sandbox Code Playgroud)

否则,如果您使用的是vanilla JavaScript,如果要将数组初始化为可变长度,则必须使用循环.

  • 请不要给出非现有命令的代码示例 (9认同)
  • 遗憾的是,由于OP更新了他的问题,因此这个答案不再有效. (3认同)

Gha*_*ani 7

以下函数返回一个填充了数字的数组:

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

请注意,使用数组构造函数创建的数组由孔组成,因此无法使用map等数组函数遍历它.因此使用该Array.apply功能.


Tom*_*Tom 7

Array(8).fill(0).map(Number.call, Number)
Run Code Online (Sandbox Code Playgroud)

窃取Igors Number.call技巧但使用fill()稍微缩短.仅适用于ES6及以上版本.


mLu*_*uby 7

Object.keys(Array.apply(0, Array(3))).map(Number)

退货[0, 1, 2].非常类似于Igor Shubin的优秀答案,但稍微不那么狡猾(而且一个字符更长).

说明:

  • Array(3) // [undefined × 3]生成长度为n = 3的数组.不幸的是,这个阵列对我们来说几乎没用,所以我们必须......
  • Array.apply(0,Array(3)) // [undefined, undefined, undefined]使数组可迭代.注意:null更常见,因为apply的第一个arg但是0更短.
  • Object.keys(Array.apply(0,Array(3))) // ['0', '1', '2'] 然后获取数组的键(因为数组是数组的类型是一个带键索引的对象).
  • Object.keys(Array.apply(0,Array(3))).map(Number) // [0, 1, 2] 并映射键,将字符串转换为数字.


Jua*_*tán 7

您可以使用函数生成器或函数*表达式.这是[ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/function ]并且函数生成器的引用链接到[ https://developer.mozilla.org/en- US/docs/Web/JavaScript/Reference/Statements/function ].

let a = 1, b = 10;

function* range(a, b) { for (var i = a; i <= b; ++i) yield i; }

Array.from(range(a, b)); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

[...range(a, b)] // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]


dab*_*eng 7

var foo = Array.from(Array(N), (v, i) => i + 1);

  • 额外的上下文可能有助于保持答案的长期价值。请考虑添加其他补充信息以扩展答案。 (4认同)

Bru*_*ier 6

我一直在寻找功能性解决方案,最后我得到了:

function numbers(min, max) {
  return Array(max-min+2).join().split(',').map(function(e, i) { return min+i; });
}

console.log(numbers(1, 9));
Run Code Online (Sandbox Code Playgroud)

注意:join().split(',')将稀疏数组转换为连续数组.

  • 这是一种非常低效的方法。它创建了 3 个数组、一个字符串,并调用了一个函数 `max - min` 次。考虑:`for (var i=max-min+1, a=[]; i--;) a[i] = min+i;` 它创建了一个数组并执行了一个循环并且编写的内容较少。;-) (2认同)

小智 6

即兴创作以上内容:

var range = function (n) {
  return Array(n).join().split(',').map(function(e, i) { return i; });
}  
Run Code Online (Sandbox Code Playgroud)

一个人可以得到以下选择:

1)Array.init到值v

var arrayInitTo = function (n,v) {
  return Array(n).join().split(',').map(function() { return v; });
}; 
Run Code Online (Sandbox Code Playgroud)

2)获得反转范围:

var rangeRev = function (n) {
  return Array(n).join().split(',').map(function() { return n--; });
};
Run Code Online (Sandbox Code Playgroud)


rad*_*soc 6

我没有看到任何基于递归函数的解决方案(并且从未编写过递归函数)所以这是我的尝试.

请注意,array.push(something)返回数组的新长度:

(a=[]).push(a.push(a.push(0))) //  a = [0, 1, 2]
Run Code Online (Sandbox Code Playgroud)

并具有递归功能:

var a = (function f(s,e,a,n){return ((n?n:n=s)>e)?a:f(s,e,a?a:a=[],a.push(n)+s)})(start,end) // e.g., start = 1, end = 5
Run Code Online (Sandbox Code Playgroud)

编辑:另外两个解决方案

var a = Object.keys(new Int8Array(6)).map(Number).slice(1)
Run Code Online (Sandbox Code Playgroud)

var a = []
var i=setInterval(function(){a.length===5?clearInterval(i):a.push(a.length+1)}) 
Run Code Online (Sandbox Code Playgroud)


T.M*_*T.M 6

您可以使用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]

Run Code Online (Sandbox Code Playgroud)

我更喜欢这样做,因为我发现它简单直接。


brf*_*f19 6

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

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

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

\n
    \n
  1. Uint8Array、Uint16Array、Uint32Array
  2. \n
  3. BigInt64Array
  4. \n
  5. Uint8ClampedArray
  6. \n
  7. 浮点数组32、浮点数组64
  8. \n
\n

当然,您将无法在这些数组中放入除数字之外的任何内容,因此使用这个小快捷方式需要您自担风险。

\n

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

\n
const arr_100_0s = new Int8Array(100)\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n
function range(start, end) {\n    const arr = new Int8Array(end - start + 1).map((curr, i) => curr + i + start);\n    return arr;\n}\n\nrange(15, 30); // Int8Array(16)\xc2\xa0[15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]\n
Run Code Online (Sandbox Code Playgroud)\n

不完全符合用户的要求,但在我看来是高度相关的。

\n


iGr*_*oza 6

简单范围生成器:

    const min = 2000;
    const max = 2022;
    const range = Array.from({ length: max - min + 1 }, (v, k) => k + min); 
    console.log('range', range);
Run Code Online (Sandbox Code Playgroud)


小智 6

const n = 5;
const arrayN = Array(n).fill('fill with anything').map((v,i)=>i);
console.log(arrayN)
Run Code Online (Sandbox Code Playgroud)


小智 5

从 1 开始:

[...Array(31).keys()].map(a=>a+1)
Run Code Online (Sandbox Code Playgroud)


Sto*_*ely 5

旧版浏览器友好的数组构造函数

如果您想要跨浏览器友好的解决方案,您仍然无法摆脱循环for。这句话在20 多年的浏览器中仍然有效,包括Internet Explorer 5-11(1998 年至今)。

for(var arr=[],i=0;i<10;i++){arr[i]=i+1};

alert(arr);// <<< [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Run Code Online (Sandbox Code Playgroud)

否则,这可以在现代 HTML5 浏览器中运行......

const arr = Array(10).fill().map((v,i)=>++i)

alert(arr);// <<< [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Run Code Online (Sandbox Code Playgroud)