在 JavaScript 中从 1..20 创建整数数组的最简单方法

IT技术 javascript algorithm
2021-02-24 22:04:59

创建此数组的最简洁方法是什么:

var x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
         11, 12, 13, 14, 15, 16, 17, 18, 19, 20];

例如,一个for循环:

var x = [];
for (var i=1;i<=20;i++) {
  x.push(i);
}

或者while循环:

var x = [], i = 1, endInt = 20;
while (i <= endInt) {
  x.push(i);
  i++;
}

是否还有其他更简洁的示例——换句话说——更少的代码?我正在考虑诸如在 Ruby 中的事情,其中​​我认为等效的代码会像1..20. 我不知道 JavaScript 中有这样的语法,但我想知道是否有更短的方法来做同样的事情。

更新:我没有考虑删除分号或var问题中的答案,但我不得不承认这个问题暗示了这一点。我对算法比对字节更感兴趣。对不起,如果我不清楚!此外,将它变成一个函数也很简单,只需轻轻拍function range(start, end) { /* guts here */ }一下它就可以了。问题是是否有解决“胆量”的新方法。

6个回答

喜欢的方法

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]:[],您可以用range1或任何名称替换 f ,但由于中间结构,这将非常慢(二次复杂性),因此永远不应使用。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)我能想到的 JavaScript标准函数的最短实现

function range1(i){return i?range1(i-1).concat(i):[]}

注意:不要在生产中使用它;它是 O(N^2)

与当前最高投票的答案对比:

function range1(i){var x=[];var i=1;while(x.push(i++)<i){};return x}

例子:

> 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 (当然,如果您无论如何都以函数式风格进行编程并且无论如何都会通过函数调用命中每个元素,那么这些都不重要。)

非常好!制作范围 1-20:function range(i) {return i>1 ? range(i-1).concat(i-1) : [];}并使用range(21);~)
2021-05-06 22:04:59
我应该提一下,虽然我的答案很简洁(按要求),但对于大范围可能效率不高,因为可悲的是 javascript 的 .concat 可能不是 O(1) 操作。
2021-05-06 22:04:59
哦,太棒了!非常巧妙地使用递归和concat() developer.mozilla.org/en/JavaScript/Reference/Global_Objects/...
2021-05-07 22:04:59
真聪明!如果我在哪里 OP 我会选择这个答案。
2021-05-11 22:04:59
第一个 ES6 替代方案可能会引发Supplied parameters do not match any signature of call target.错误。这是因为fill()Array 原型中方法必须接收填充值。查看我的解决方案以使用该fill()方法。
2021-05-19 22:04:59

它可以使用 ES6 的功能来完成,目前只有 Firefox 支持。我在这里找到了一个兼容性表:http : //kangax.github.io/compat-table/es6/

Array.from(new Array(20), (x,i) => i+1)

如果你想有一些其他的范围,那么我想你可以做

Array.from(new Array(5), (x,i) => i+5)

那么这将是 [5,6,7,8,9]

这在 Chrome v45 中有效,如果您使用 Babel 转译 ES6,则可以使用。你也可以这样做Array.from({ length: 20 }, (v, k) => k + 1);
2021-05-11 22:04:59

您可以使用 while 循环执行此操作,其中推送发生在条件内部。Array.push 返回数组的长度,该长度恰好与本例中的值相同。因此,您可以执行以下操作:

x = []; //normally would use var here
i = 1;  //normally would use var here
while(x.push(i++)<20){}

//at this point, x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

精简版(31 个字符)

x=[];i=1;while(x.push(i++)<20);

jsFiddle 示例

他通过不使用 var 来节省空间,但是如果您实现了这一点,请使用 var,否则维护您代码的人会找到您...
2021-05-02 22:04:59
哦!我喜欢。不过很变态。我的理解是.push()返回数组的长度。在 Mozilla Docs 中:developer.mozilla.org/en/JavaScript/Reference/Global_Objects/... “push 方法对于轻松地将值附加到数组很有用。此方法的返回值是对象的新长度属性,在该属性上方法被调用。” 碰巧在以 1 开头的数组中,最后一个push()ed 将是长度。哈!
2021-05-04 22:04:59
@EndangeredMassa, x.Push() 返回新长度而不是值。
2021-05-10 22:04:59
没错。在这种特定情况下,它们是相同的。
2021-05-16 22:04:59
@濒临灭绝的马萨。x.push(i++) 是否等于 x 中的元素数?
2021-05-18 22:04:59

而--是要走的路

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

返回 [1,2,3,4,5,6,7,8,9,10]

用开始和长度解释

var array=[],length=20,start=5;while(length--)array[length]=length+start

返回 [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]

想要范围?

用开始和结束解释

var array=[],end=30,start=25,a=end-start+1;while(a--)array[a]=end--

返回 [25, 26, 27, 28, 29, 30]

为了 -

for(var a=[],b=20;b>0;b--,a[b]=b+1)

对于++

for(var a=[],b=0;b<20;b++,a[b]=b+1)

为什么要走这条路?

  1. while -- 是最快的循环;

  2. 直接设置比 push & concat 更快;

  3. [] 也比 new Array(10) 快;

  4. 它的代码并不比所有其他代码长

字节保存技术:

  1. 使用参数作为函数变量的占位符
  2. 如果不需要,不要使用 new Array(),push(),concat()
  3. 仅在需要时放置 "(){};,"。
  4. 在短函数中使用 a,b,c,d...。

所以如果你想要一个功能

开始,结束(范围)

function range(a,b,c,d){d=[];c=b-a+1;while(c--)d[c]=b--;return d}

所以现在 range(3,7) 返回 [3,4,5,6,7]

你在这里以多种方式保存字节,这个函数也非常快,因为它不使用 concat、push、new Array 并且它是用一段时间制作的——

如果你对 0-20 没问题,这里是我最近的代码高尔夫的最新最爱:

[...'0'.repeat(21)].map((_,i)=>i)
Array.from({length:21},(_,i)=>i)
Array(21).fill().map((_,i)=>i)
[...Array(21)].map((_,i)=>i)
Array(21).map((_,i)=>i)
[...Array(21).keys()]