46

What's the most efficient way to create this simple array dynamically.

var arr = [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"];

Let's say we can get the number 10 from a variable

var mynumber = 10;
g19fanatic
  • 10,567
  • 6
  • 33
  • 63
Sam
  • 1,453
  • 3
  • 15
  • 23

17 Answers17

88
var arr = [];
for(var i=1; i<=mynumber; i++) {
   arr.push(i.toString());
}
Nadh
  • 6,987
  • 2
  • 21
  • 21
  • 1
    it is not very healthy to expand the array on every loop, this is almost inevitable is most of the time, but this time we know the length. (see my ans for more info) – ajax333221 May 04 '12 at 18:06
25

With ES2015, this can be achieved concisely in a single expression using the Array.from method like so:

Array.from({ length: 10 }, (_, idx) => `${++idx}`)

The first argument to from is an array like object that provides a length property. The second argument is a map function that allows us to replace the default undefined values with their adjusted index values as you requested. Checkout the specification here

Just About Jeff
  • 271
  • 3
  • 5
  • one thing to mention: you can use any variable name instead of '_', the first property of the map function represents the current value of the Arrays element ( arr[idx] ). in this example it is always 'undefined' – Lusk116 Mar 16 '17 at 21:08
17

Update: micro-optimizations like this one are just not worth it, engines are so smart these days that I would advice in the 2020 to simply just go with var arr = [];.

Here is how I would do it:

var mynumber = 10;
var arr = new Array(mynumber);

for (var i = 0; i < mynumber; i++) {
    arr[i] = (i + 1).toString();
}

My answer is pretty much the same of everyone, but note that I did something different:

  • It is better if you specify the array length and don't force it to expand every time

So I created the array with new Array(mynumber);

ajax333221
  • 11,436
  • 16
  • 61
  • 95
  • 3
    Why is it bad/not recommended to expand the array on every iteration? Does it affect the memory allocation or the time taken to store the value? Can you please elaborate on the drawbacks? – Yash Kalwani Apr 26 '18 at 12:14
  • @YashKalwani basically work like copy and paste. if we haven't allocated a fixed size in memory there might be a new item placed near the last previous index. so compilers will instruct OS to copy this to another location and then insert it. – thatcoder Jul 26 '22 at 20:23
10

This answer is about "how to dynamically create an array without loop".

Literal operator [] doesn't allow us to create dynamically, so let's look into Array, it's constructor and it's methods.

In ES2015 Array has method .from(), which easily allows us to create dynamic Array:

Array.from({length: 10}) // -> [undefined, undefined, undefined, ... ]

When Array's constructor receives number as first parameter, it creates an Array with size of that number, but it is not iterable, so we cannot use .map(), .filter() etc. :

new Array(10) // -> [empty × 10]

But if we'll pass more than one parameter we will receive array from all parameters:

new Array(1,2,3) // -> [1,2,3]

If we would use ES2015 we can use spread operator which will spread empty Array inside another Array, so we will get iterable Array :

[...new Array(10)]  // -> [undefined, undefined, undefined, ...]

But if we don't use ES2015 and don't have polyfills, there is also a way to create dynamic Array without loop in ES5. If we'll think about .apply() method: it spreads second argument array to params. So calling apply on Array's constructor will do the thing:

Array.apply(null, new Array(10))  // -> [undefined, undefined, undefined, ...]

After we have dynamic iterable Array, we can use map to assign dynamic values:

Array.apply(null, new Array(10)).map(function(el, i) {return ++i + ""})

// ["1","2","3", ...]
Anton Temchenko
  • 1,440
  • 1
  • 13
  • 28
4

Sounds like you just want to construct an array that contains the string versions of the integer values. A simple approach:

var arr = [];
for (var i = 1; i <= mynumber; i++) arr.push(""+i);

For a more interesting version you could do a generator...

function tail(i, maxval) {
    return [i].concat(i < maxval ? tail(i+1, maxval) : []);
}

var arr = tail(1, mynumber);
koblas
  • 25,410
  • 6
  • 39
  • 49
2
var arr = [];
while(mynumber--) {
    arr[mynumber] = String(mynumber+1);
}
David Hellsing
  • 106,495
  • 44
  • 176
  • 212
  • This was my first thought. Efficient and concise. – Erik Reppen May 04 '12 at 15:50
  • Might be faster to join/re-split the integer array in these examples than to convert one at a time. e.g. after the loops: `arr=arr.join('_').split('_');` and remove the `String()` steps. – Erik Reppen May 04 '12 at 18:49
2

I would do as follows;

var num = 10,
  dynar = [...Array(num)].map((_,i) => ++i+"");
console.log(dynar);
Redu
  • 25,060
  • 6
  • 56
  • 76
2

A little late to this game, but there is REALLY cool stuff you can do with ES6 these days.

You can now fill an array of dynamic length with random numbers in one line of code!

[...Array(10).keys()].map(() => Math.floor(Math.random() * 100))
Ben
  • 5,085
  • 9
  • 39
  • 58
2

Since none of previous answers provide solution with repeat Here you go:
To generate dynamic array of ten numbers with repeat:

[...'x'.repeat(10).split('').keys()]
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

To get what you want:

var arr = [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"];

Just add one to all of elements keys (since array are zero-based) and convert numbers to string by string literals or .toString() or even just add empty space to number ''+x.

let mynumber = 10;

const keys = [...'x'.repeat(mynumber).split('').keys()]
const arr = keys.map(x=>`${x+1}`);
//['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
XMehdi01
  • 5,538
  • 2
  • 10
  • 34
1

misread the question, corrected. Try:

var myNumber = 100,
    myarr = (function arr(i){return i ? arr(i-1).concat(i) : [i]}(myNumber));

Just for fun, if you extend Array like this:

Array.prototype.mapx = function(callback){
  return String(this).split(',').map(callback);
}

You could use:

var myNum = 100, 
    myarr = new Array(myNum).mapx(function(el,i){return i+1;});
KooiInc
  • 119,216
  • 31
  • 141
  • 177
1
var arr = [];
for(var i=1; i<=mynumber; i++) {
   arr.push("" + i);
}

This seems to be faster in Chrome, according to JSPerf, but please note that it is all very browser dependant.

There's 4 things you can change about this snippet:

  1. Use for or while.
  2. Use forward or backward loop (with backward creating sparse array at beginning)
  3. Use push or direct access by index.
  4. Use implicit stringification or explicitly call toString.

In each and every browser total speed would be combination of how much better each option for each item in this list performs in that particular browser.

TL;DR: it is probably not good idea to try to micro-optimize this particular piece.

Oleg V. Volkov
  • 21,719
  • 4
  • 44
  • 68
1

I had a similar problem and a solution I found (forgot where I found it) is this:

Array.from(Array(mynumber), (val, index) => index + 1)

Vlad
  • 33
  • 1
  • 5
0

If you are asking whether there is a built in Pythonic range-like function, there isn't. You have to do it the brute force way. Maybe rangy would be of interest to you.

Explosion Pills
  • 188,624
  • 52
  • 326
  • 405
0

I hope you have to get last element from array variable so my solution

var arr = [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"];
var mynumber = arr [arr .length - 1];
//var mynumber = 10;
Samyappa
  • 535
  • 2
  • 11
0

Some of us are referring to use from which is not good at the performance:

function getArrayViaFrom(input) {
  console.time('Execution Time');
  let output = Array.from(Array(input), (value, i) => (i + 1).toString())
  console.timeEnd('Execution Time');

  return output;
}

function getArrayViaFor(input) {
  console.time('Execution Time 1');
  var output = [];
  for (var i = 1; i <= input; i++) {
    output.push(i.toString());
  }
  console.timeEnd('Execution Time 1');

  return output;
}

console.log(getArrayViaFrom(10)) // Takes 10x more than for that is 0.220ms
console.log(getArrayViaFor(10))  // Takes 10x less than From that is 0.020ms
Soham
  • 705
  • 3
  • 19
0

updated = > june 2020

if are you using node js you can create or append a string value with " ," operator then inside the loop you can

for (var j = 0; j <= data.legth -1; j++) {
                    lang += data.lang  +", " ;

                }

 var langs = lang.split(',')
 console.log("Languages =>",  lang, typeof(lang), typeof(langs), langs) 
 console.log(lang[0]) // here access arrary by index value
            

you can see the type of string and object

Community
  • 1
  • 1
Mr Coder
  • 507
  • 3
  • 13
-3

The same way you would for all arrays you want to fill dynamically. A for loop. Suedo code is

arr =array()
for(i; i<max; i++){
 arr[]=i

}

that should help you on the way

arrowd
  • 33,231
  • 8
  • 79
  • 110
  • 1
    use `var i` to avoid globals, use `new Array()` or even better `[]` instead of `array()`, give `i` a start value, specify an index here `arr[]=...`, make the values strings, the range isn't correct (you need to use `<=` or adjust the range by adding +1 or something) – ajax333221 May 04 '12 at 17:46