7

I'm brand new to javascript. I was working through a problem earlier where I needed an array that included the numbers 1 thru 20.

I did this with the following:

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

QUESTION:

I can't help but think that this is not efficient (and certainly not scalable). Is there a way to create an array that automatically populates with sequential values between 1 and 20, or 1 and 1000 for instance?

Phil Powis
  • 183
  • 2
  • 2
  • 9
  • 1
    Why not use a for loop instead of the array? – Ed Heal Oct 12 '13 at 17:46
  • 1
    You can make a for loop, but then you could use just a for loop... what do you want to do? – Sergio Oct 12 '13 at 17:46
  • 2
    Yes, but the result doesn't sound useful. –  Oct 12 '13 at 17:46
  • 1
    If you need this for your [FizzBuzz program](http://stackoverflow.com/questions/19337013/understanding-difference-in-results-between-two-code-solutions), the answer is that the entire array there is unnecessary (you can set the range in an integer and print the result using `i+1`). – JJJ Oct 12 '13 at 17:50
  • I am no longer using an array as part of my fizzbuzz solution, but am trying to understand different approaches and how to make them more efficient. Using the array (even though this is not the best approach) I wanted to learn if I could create the array without listing it out explicity. Sounds like another for loop to solve this is the answer. I hadn't gotten to .push yet in my learning, but this is very useful! – Phil Powis Oct 12 '13 at 17:53
  • 2
    The point is that you will never need an array that regular because you can calculate the necessary value on the fly. – JJJ Oct 12 '13 at 17:55

2 Answers2

14

Here's a oneliner:

var myArr = Array(20).join().split(',').map(function(a){return this.i++},{i:1});

or a tiny bit shorter:

var myArr = (''+Array(20)).split(',').map(function(){return this[0]++;}, [1]);

Both methods create an empty Array with 20 empty elements (i.e. elements with value undefined). On a thus created Array the map method can't be applied 1, so the join (or string addition) and split trick transforms it to an Array that knows it. Now the map callback (see the MDN link) does nothing more than sending an increment of the initial value ({i:1} or [1]) back for each element of the Array, and after that, myArr contains 20 numeric values from 1 to 20.

Addendum: ES20xx

[...Array(21).keys()].slice(1);

Array.map => See also...

See also this Stackblitz project.

1 Why not? See this SO answer, and this one for a more profound explanation

KooiInc
  • 119,216
  • 31
  • 141
  • 177
  • wow thats pretty even though I dont understand how it works. the other answer above I get because I've worked with the for loop. I'll have to dig into this :) – Phil Powis Oct 12 '13 at 17:56
  • Hi @PhilPowis, I added a bit of explanation to my answer, hope it helps you along. – KooiInc Oct 12 '13 at 18:11
  • 1
    Very nice - about twice as efficient as the most efficient for loop solution at 10000000 iterations, at least in Chrome. – cori Oct 12 '13 at 18:14
  • @KooiInc it's a bit confusing to say '_Array(20) doesn't know the map method_', the map method is actually there _Array(20).toString()===Array(20).map(function(a){return 'a'}).toString()_ (see this http://stackoverflow.com/a/20333745/3116322) – Ande Jul 02 '14 at 17:10
  • @Ande: yep, reformulated the answer, added your link and another – KooiInc Jul 03 '14 at 06:47
11

You could use a simple loop to do what you want;

var numberArray = [];

for(var i = 1; i <= 20; i++){
    numberArray.push(i);
}

console.log(numberArray); 
Nick
  • 560
  • 6
  • 19