Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tersest way to create an array of integers from 1..20 in JavaScript

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."

like image 763
artlung Avatar asked Jun 09 '11 21:06

artlung


People also ask

How do you make an array of numbers in JavaScript?

var rank = new Array(1, 2, 3, 4); The Array parameter is a list of strings or integers. When you specify a single numeric parameter with the Array constructor, you specify the initial length of the array.

What are the ways to create array in JavaScript?

Creating an ArrayUsing an array literal is the easiest way to create a JavaScript Array. Syntax: const array_name = [item1, item2, ...]; It is a common practice to declare arrays with the const keyword.

How do you create an array of integers?

To initialize or instantiate an array as we declare it, meaning we assign values as when we create the array, we can use the following shorthand syntax: int[] myArray = {13, 14, 15}; Or, you could generate a stream of values and assign it back to the array: int[] intArray = IntStream.

Can you convert number to array in JavaScript?

Typecast the integer into a string. Using the split() method to make it an array of strings. Iterate over that array using the map() method. Using the map() method returns the array of strings into an array of Integers.


1 Answers

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] 

Note the above does a tiny bit of extra work (fills with undefined) but is relatively minor vis-a-vis the speedup you can achieve by using a for loop, and if you forget the .fill you may be confused why your array is mysteriously [empty x 5]. You can encapsulate the above as a custom function, or alternatively use a somewhat more intended method:

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

You can of course directly go from that into whatever you want to do, like python's list comprehensions e.g. [i**2 for i in range(5)]:

> Array.from(Array(5), (_,i)=> i**2) [0, 1, 4, 9, 16] 

... or if you want to get more complicated...:

> Array.from(Array(5), (_,i)=> {     const R = /*some computation*/;     return /*etc*/; }); 

[edit May,2021]: theoretically tersest way of defining such a function nowadays is f=i=>i?[...f(i-1),i]:[], where you replace f with range1 or whatever the name is, but which would be very slow (quadratic complexity) due to intermediate structures so should never be used. f=i=>i?f(i-1)&&x.push(i)&&x:x=[] is linear complexity but relies on abuse of notation and is unreadable and pollutes global variables as well. But, since defining arrow functions (which don't bind but rather inherit this) is pretty terse nowadays, you could just wrap the above solution:

const range1 = n=> Array.from(Array(n), (_,i)=> i+i); // range1(5)==[1, 2, 3, 4, 5] 

everything below is historical:

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.


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.)

like image 62
ninjagecko Avatar answered Sep 29 '22 05:09

ninjagecko