Tersest way to create an array of integers from 1.

2020-01-27 02:37发布

What would be the tersest way to create this array:

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

For example, a for loop:

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

Or a while loop:

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

Would there be other examples that would be terser -- in other words -- less code? I'm thinking of things like in Ruby where the equivalent code I believe would be as simple as 1..20. I'm not aware of syntax like that in JavaScript but I'm wondering if there are shorter ways to do that same thing.

UPDATE: I wasn't thinking of removing semicolons or var for answers in the question, but I have to admit the question implies that. I am more curious about algorithms than shaving bytes. Sorry if I was unclear! Also, making it into a function is simple enough, just slap function range(start, end) { /* guts here */ } around it and you're there. The question is are there novel approaches to the "guts."

12条回答
Anthone
2楼-- · 2020-01-27 02:48

You can do this with a while loop where the push happens inside the condition.Array.push returns the length of the array, which happens to be the same as the value in this case. So, you can do the following:

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]

Condensed version (31 characters)

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

jsFiddle example

查看更多
Rolldiameter
3楼-- · 2020-01-27 02:48

You could always create a function...

function createNumArray(a, b) {
   var arr = [], 
       i = a;

    while((arr[arr.length] = i) < b) {i++}
    return arr;
}

Which allows you to write succinct code later on such as...

var arr = createNumArray(1, 20);
查看更多
【Aperson】
4楼-- · 2020-01-27 02:55

I'd extend Array's prototype to make it simple to access:

Array.prototype.range = function(start, end) {
    if (!this.length) {
        while (end >= start) {
            this.push(start++);
        }
    } else {
        throw "You can only call 'range' on an empty array";
    }
    return this;
};

var array = [].range(1, 20);

While the above is the nearest I can think of with respect to the syntactic sugar you're looking for, you may want to try out CoffeeScript.

It supports the notation you're after.

CoffeeScript:

test = [1..20]

alert test

Renders to JavaScript:

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

You can try out live examples on their site, and see the conversion it does as you type.

Just click the TRY COFFEESCRIPT link at the top, and you'll get a console where you can test some code.

查看更多
手持菜刀,她持情操
5楼-- · 2020-01-27 02:57

I can't think of a way with less characters than ~46:

var a=[];while(a.length<20)a.push(a.length+1);

Granted, you could make a function out of that.

Reading your comments about a function, you could do something like

var range = function (start, end) {
    var arr = [];

    while (start <= end) {
        arr.push(start++)
    }

    return arr;
};

Then range(1, 20) would return the array as expected.

查看更多
神经病院院长
6楼-- · 2020-01-27 02:58

I suppose this is the shortest way:

var i=0, arr = [];
while (i++<20){
  arr.push(i);
}

or associating on the 'perverse' code in EndangeredMassa's answer:

var i,arr; while (i=i||1, (arr=arr||[]).push(i++)<20){}
查看更多
一纸荒年 Trace。
7楼-- · 2020-01-27 03:03

After thinking about it a bit, this is the shortest implementation of the standard range(N) function in JavaScript I could come up with:

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

Note: Do not use this in production; it's O(N^2)

Contrast with current top-voted answer:

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

Example:

> range1(5)
[1, 2, 3, 4, 5]

This is like the poster child for recursion, though I was expecting it to be longer until I thought of ternary-if-statement, which brings it down to 42 necessary characters.

Note that the "standard" range function returning [start,end) can be written by doing .concat(i-1).


Update: Ooh, I discovered an incredibly short version with ugly imperative syntax by abusing for loops, reverse-ordering, the fact that assignments return a value: for(y=[],i=20;y[--i]=i;){} consisting of only 25 characters (though you will want var y which you can insert into a for loop, and +1 if you don't want 0...19). While it is not shorter if you need to define a function, it is shorter than i?r(i-1).concat(i):[] if you do not need to make a function.


Favorite method

Update Sep13,2015:

Just came up with this new method which works with browsers which support the ES6 standard:

> Array(5).fill().map((x,i)=>i)
[0, 1, 2, 3, 4]

Also this:

> Array.from(Array(5),(x,i)=>i)
[0, 1, 2, 3, 4]

Added some performance profiling testcases: it seems that everything besides a standard in-order for-loop is 10x slower, at least on V8. https://jsperf.com/array-range-in-javascript (Of course, none of this matters if you're programming in a functional style anyway and would hit every element with a function call anyway.)

查看更多
登录 后发表回答