最喜欢的方法
2015 年 9 月 13 日更新:
刚刚想出了这个新方法,它适用于支持 ES6 标准的浏览器:
> Array(5).fill().map((x,i)=>i)
[0, 1, 2, 3, 4]
请注意,上面做了一点额外的工作(填充undefined
)但是相对于使用 for 循环可以实现的加速而言相对较小,如果您忘记了.fill
您可能会感到困惑为什么您的数组很神秘[empty x 5]
。您可以将上述内容封装为自定义函数,或者使用更有意向的方法:
> Array.from(Array(5),(x,i)=>i)
[0, 1, 2, 3, 4]
你当然可以直接从那里进入你想做的任何事情,比如Python的列表理解,例如[i**2 for i in range(5)]
:
> Array.from(Array(5), (_,i)=> i**2)
[0, 1, 4, 9, 16]
...或者如果你想变得更复杂...:
> Array.from(Array(5), (_,i)=> {
const R = /*some computation*/;
return /*etc*/;
});
[2021 年 5 月编辑]:理论上定义此类函数的最简洁方法是f=i=>i?[...f(i-1),i]:[]
,将 f 替换为range1
或无论名称是什么,但由于中间结构,这会非常慢(二次复杂度),因此永远不应该使用。f=i=>i?f(i-1)&&x.push(i)&&x:x=[]
是线性复杂度,但依赖于符号的滥用,并且不可读并且还会污染全局变量。但是,由于定义了箭头函数(它不绑定而是继承this
)现在非常简洁,您可以将上面的解决方案包装起来:
const range1 = n=> Array.from(Array(n), (_,i)=> i+i);
// range1(5)==[1, 2, 3, 4, 5]
根据情况,最简洁的方法是range(N)
,如果您已经有一个长度恰好为 N 的列表,则只需map
它:例如而不是做Array.from(Array(myArr.length), (_,i)=> i**2)
,你会这样做myArr.map((_,i)=> i**2)
。 (除非您愿意,否则这没有副作用。)
下面的一切都是历史的:
想了一下,这是标准的最短实现range(N)
JavaScript 中的函数我可以想出:
function range1(i){return i?range1(i-1).concat(i):[]}
Note:不要在生产中使用它;是 O(N^2)
与当前得票最高的答案对比:
function range1(i){var x=[];var i=1;while(x.push(i++)<i){};return x}
Example:
> range1(5)
[1, 2, 3, 4, 5]
这就像递归的典型例子,尽管我原以为它会更长,直到我想到三元 if 语句,这将其减少到 42 个必要字符。
注意“标准”range
返回 [start,end) 的函数可以这样写.concat(i-1)
.
更新:哦,我发现了一个令人难以置信的简短版本,它通过滥用 for 循环、反向排序以及赋值返回一个值的事实,具有丑陋的命令式语法:for(y=[],i=20;y[--i]=i;){}
仅包含 25 个字符(尽管您会想要var y
您可以将其插入 for 循环,如果您不需要 0...19,则+1)。虽然如果您需要定义一个函数,它并不短,但它比i?r(i-1).concat(i):[]
如果你不需要做一个功能。
添加了一些性能分析测试用例:似乎除了标准的有序 for 循环之外的所有内容都慢了 10 倍,至少在 V8 上是这样。https://jsperf.com/array-range-in-javascript https://jsperf.com/array-range-in-javascript(当然,如果您无论如何都以函数式风格进行编程并且无论如何都会通过函数调用来访问每个元素,那么这一切都不重要。)