views:

150

answers:

6

Hi there,

I'm looking for any alternatives to the below for creating a JavaScript array containing 1 through to N where N is only known at runtime.

var foo = [];

for (var i = 1; i <= N; i++) {
   foo.push(i);
}

To me it feels like there should be a way of doing this without the loop.

Cheers for any ideas.

+1  A: 

Try this:

var foo = [1, 2, 3, 4, 5];

Unfortunately, Javascript doesn't have a construct in place to do something like this:

var foo = [1..5]; 

So, it looks like you'll have to use a for loop if you want to initialize an array up to a variable length.

Zach Rattner
+1 more clarity than other answers, also includes "why"
Nader Shirazie
This answer is unfortunately not valid anymore since the OP updated his question.
BalusC
A: 

Well, you could ditch the loop and do this:

var foo = [1,2,3,4,5];
xil3
@Zach You down voted me because you happened to type faster than me? lol... your answer wasn't displayed when I was typing mine. Maybe you're new here, but get a damn clue.
xil3
@Zach: Agree with @xil3. You can't downvote someone just because their answer is similar to yours.
missingfaktor
Actually Zach, your answer was the duplicate. xil3 answered a whole minute before you. I took away my downvote from yours only because you added the extra bit. Originally, your answer was almost the exact same of xil3's.
vol7ron
@xil3, if your answer was the duplicate, I'd say a downvote is valid. You should delete your answer if it's the same and posted after, whether if it's because you're a slower typer or for some other reason. Each answer should be independent. In your case, your answer was first... and then zach's came. So you shouldn't be penalized for that.
vol7ron
+6  A: 
function range(start, end)
{
    var foo = [];
    for (var i = start; i <= end; i++)
        foo.push(i);
    return foo;
}

Then called by

var foo = range(1, 5);

There is no built-in way to do this in Javascript, but it's a perfectly valid utility function to create if you need to do it more than once.

Edit: In my opinion, the following is a better range function. Maybe just because I'm biased by LINQ, but I think it's more useful in more cases. Your mileage may vary.

function range(start, count)
{
    if(arguments.length == 1)
    {
        count = start;
        start = 0;
    }

    var foo = [];
    for (var i = 0; i < count; i++)
        foo.push(start + i);
    return foo;
}
Ian Henry
I like this. If you wanted to go the extra mile with it, you could declare it as Array.prototype.range = function(start, end) { ... };. Then, you can call range(x, y) on any Array object.
Zach Rattner
Rather make it a method of `Array` instead of `Array.prototype` as there is no reason (it might even be considered rather dumb) to have this method on every array.
adamse
`Array.range(1, 5)` would probably be more appropriate, but there is something kind of cool about writing `[].range(1, 5)`.
MooGoo
+2  A: 

If I get what you are after, you want an array of numbers 1..n that you can later loop through.

If this is all you need, can you do this instead?

var foo = new Array(45);//create a 45 element array

then when you want to use it... (un-optimized, just for example)

for(var i=0;i<foo.length;i++){
  document.write('Item: ' + (i+1) + ' of ' + foo.length + '<br/>'); 
}

e.g. if you don't need to store anything in the array, you just need a container of the right length that you can iterate over... this might be easier.

See it in action here: http://jsfiddle.net/3kcvm/

scunliffe
@scunliffe - impressed you managed to phrase my question better than I could, you are indeed correct as on reflection all I need is an array of numbers that I can later loop through :) Thanks for your answer.
Godders
@Godders: If this is what you're looking for, why do you need an array? A simple `var n = 45;` and then looping from `1..n` would do.
casablanca
@casablanca: of course you are correct, can't believe i couldn't spot the simple answer before posting the question. Oh well, got there in the end. Thanks!
Godders
@Godders - To note, if you want to decrease the size of the array after it is created to length M, simply use `foo.length = M` --- The cut off info is lost. See it in action ==> http://jsfiddle.net/ACMXp/
Peter Ajtai
A: 

I know your answer is asking to populate an array numerically, but I'm uncertain why you'd want to do this? Arrays are unnecessary for this.


You may just want to declare an array of a certain size:

var foo = new Array(N);   // where N is a positive integer

/* this will create an array with a number of elements, N; 
   each element will contain a default value of 'undefined' */


Otherwise, you'd want to create a function as others suggested, or use the loop construct as in your question.

vol7ron
This appears to be a similar answer to the solution **scunliffe** posted, whom I credit to posting before me :)
vol7ron
+1  A: 

Just for fun, I wanted to build off of Ian Henry's answer.

Of course var array = new Array(N); will give you an array of size N, but the keys and values will be identical.... then to shorten the array to size M, use array.length = M.... but for some added functionality try:

function range()
{
    // This function takes optional arguments:
    // start, end, increment
    //    start may be larger or smaller than end
    // Example:  range(null, null, 2);

    var array = []; // Create empty array

      // Get arguments or set default values:
    var start = (arguments[0] ? arguments[0] : 0);
    var end   = (arguments[1] ? arguments[1] : 9);
      // If start == end return array of size 1
    if (start == end) { array.push(start); return array; }
    var inc   = (arguments[2] ? Math.abs(arguments[2]) : 1);

    inc *= (start > end ? -1 : 1); // Figure out which direction to increment.

      // Loop ending condition depends on relative sizes of start and end
    for (var i = start; (start < end ? i <= end : i >= end) ; i += inc)
        array.push(i);

    return array;
}

var foo = range(1, -100, 8.5)

for(var i=0;i<foo.length;i++){
  document.write(foo[i] + ' is item: ' + (i+1) + ' of ' + foo.length + '<br/>'); 
}​

Output of the above:

1 is item: 1 of 12
-7.5 is item: 2 of 12
-16 is item: 3 of 12
-24.5 is item: 4 of 12
-33 is item: 5 of 12
-41.5 is item: 6 of 12
-50 is item: 7 of 12
-58.5 is item: 8 of 12
-67 is item: 9 of 12
-75.5 is item: 10 of 12
-84 is item: 11 of 12
-92.5 is item: 12 of 12

jsFiddle example

This function makes use of the automatically generated arguments array.

The function creates an array filled with values beginning at start and ending at end with increments of size increment, where

range(start, end, increment);

Each value has a default and the sign of the increment doesn't matter, since the direction of incrementation depends on the relative sizes of start and end.

Peter Ajtai