167

How can I create an array with 40 elements, with random values from 0 to 39 ? Like

[4, 23, 7, 39, 19, 0, 9, 14, ...]

I tried using solutions from here:

http://freewebdesigntutorials.com/javaScriptTutorials/jsArrayObject/randomizeArrayElements.htm

but the array I get is very little randomized. It generates a lot of blocks of successive numbers...

Kamil Kiełczewski
  • 85,173
  • 29
  • 368
  • 345
Alexandra
  • 1,745
  • 2
  • 11
  • 4

24 Answers24

369

The shortest approach (ES6):

// randomly generated N = 40 length array 0 <= A[N] <= 39
Array.from({length: 40}, () => Math.floor(Math.random() * 40));
Nick is tired
  • 6,860
  • 20
  • 39
  • 51
Simon Borsky
  • 4,979
  • 2
  • 22
  • 20
  • You are right. Deleted my comment. Corrected version of the actual shortest way: [...Array(20)].map(()=>{return Math.floor(Math.random()*30)}); – jaheraho Apr 03 '18 at 19:10
  • 18
    If we remove spaces from the answer's approach, it's 4 fewer characters than the one you proposed. Of course, if you're interested in playing golf, you actually left out some easy character-cutting shortcuts: `[...Array(40)].map(_=>Math.ceil(Math.random()*40));` would be 11 characters fewer than yours, and 7 fewer than the original. – Kyle Baker Apr 19 '18 at 18:38
  • (wasn't quick enough to correct--needs to be *39 to meet the OP's criteria if we use `Math.ceil`, though we cut out 0 as an option. If we can accept 1-40 instead of 0-39, this works. Otherwise, reduce a character of improvement for going back to `Math.floor`) – Kyle Baker Apr 19 '18 at 18:46
68

Here's a solution that shuffles a list of unique numbers (no repeats, ever).

for (var a=[],i=0;i<40;++i) a[i]=i;

// http://stackoverflow.com/questions/962802#962890
function shuffle(array) {
  var tmp, current, top = array.length;
  if(top) while(--top) {
    current = Math.floor(Math.random() * (top + 1));
    tmp = array[current];
    array[current] = array[top];
    array[top] = tmp;
  }
  return array;
}

a = shuffle(a);

If you want to allow repeated values (which is not what the OP wanted) then look elsewhere. :)

Phrogz
  • 296,393
  • 112
  • 651
  • 745
  • 5
    This solution is good if the numbers should be unique, but this is a completely different statistical/probabilistic thing. I hope this was clear to the OP and was not relevant in their case, but in certain cases it can have a big impact on the correctness of the program. (I'm not critizing the answer, just raising a flag for future readers. You might want to mention that.) See also: https://en.wikipedia.org/wiki/Combination (distinction between "with" or "without repetition" – chiccodoro Aug 25 '14 at 16:06
  • 1
    var random_array = new Array(40).fill().map((a, i) => a = i).sort(() => Math.random() - 0.5); I think this does the same as above – Jamie337nichols Sep 16 '19 at 18:47
  • How to exclude it from generating the number 0? – Gosi Sep 19 '19 at 04:51
  • Here is an ES6 version that allows you some flexibility of min/max but still gets you an array of unique numbers: http://pastie.org/p/069IAzSzsRhN6JXdAIpPhc – Curt Sep 16 '20 at 05:46
58

Shortest:

[...Array(40)].map(e=>~~(Math.random()*40))
Nick is tired
  • 6,860
  • 20
  • 39
  • 51
Curt
  • 794
  • 7
  • 8
53

ES5:

function randomArray(length, max) {
    return Array.apply(null, Array(length)).map(function() {
        return Math.round(Math.random() * max);
    });
}

ES6:

randomArray = (length, max) => [...new Array(length)]
    .map(() => Math.round(Math.random() * max));
Eugene Kulabuhov
  • 2,349
  • 1
  • 26
  • 25
  • 1
    What's up with the ```_``` and ```i``` arguments? unnecessary in ES6 unless I'm mistaken. – AfricanMatt Feb 10 '17 at 06:06
  • 2
    @AfricanMatt, `_` is the current element and `i` is the current index. You're right, they are unnecessary in both cases. You can remove them if you like. – Eugene Kulabuhov Feb 10 '17 at 17:16
  • 2
    I don't know where you believe that version for ES6 works? Array.from works... here is an example with your code... randomArray = (length: number, max: number) => Array.from({length}) .map(() => Math.floor(Math.random() * max)); – Christian Matthew Aug 22 '17 at 00:38
  • @EugeneKulabuhov why would you do `[...new Array(length)]` when you can just do `new Array(length)` ? – Magne Mar 19 '22 at 17:32
  • This is what I was searching for – Ariful Islam Jun 20 '22 at 21:07
49

Even shorter ES6 approach:

Array(40).fill().map(() => Math.round(Math.random() * 40))

Also, you could have a function with arguments:

const randomArray = (length, max) => 
  Array(length).fill().map(() => Math.round(Math.random() * max))
Damjan Pavlica
  • 31,277
  • 10
  • 71
  • 76
17

Math.random() will return a number between 0 and 1(exclusive). So, if you want 0-40, you can multiple it by 40, the highest the result can ever be is what you're multiplying by.

var arr = [];
for (var i=0, t=40; i<t; i++) {
    arr.push(Math.round(Math.random() * t))
}
document.write(arr);

http://jsfiddle.net/robert/tUW89/

Phrogz
  • 296,393
  • 112
  • 651
  • 745
Robert
  • 21,110
  • 9
  • 55
  • 65
  • 1
    To clarify: that's a letter L, not the number 1, in "l = 40", "i < l" and "Math.random() * l". The font makes it hard to tell. – Mu Mind Apr 29 '11 at 20:17
12
const randomNumber = Array.from({length: 6}, () => Math.floor(Math.random() * 39));

limited the array to 6 values to make it easy to see.

Audwin Oyong
  • 2,247
  • 3
  • 15
  • 32
Rafael
  • 131
  • 1
  • 5
11

.. the array I get is very little randomized. It generates a lot of blocks of successive numbers...

Sequences of random items often contain blocks of successive numbers, see the Gambler's Fallacy. For example:

.. we have just tossed four heads in a row .. Since the probability of a run of five successive heads is only 1⁄32 .. a person subject to the gambler's fallacy might believe that this next flip was less likely to be heads than to be tails. http://en.wikipedia.org/wiki/Gamblers_fallacy

Jared Beck
  • 16,796
  • 9
  • 72
  • 97
  • +1 exactly. One needs to decide whether one needs real (statistically) random numbers, or numbers that "look random". – chiccodoro Aug 25 '14 at 16:08
10

Because * has higher precedence than |, it can be shorter by using |0 to replace Math.floor().

[...Array(40)].map(e=>Math.random()*40|0)
sup39
  • 1,081
  • 5
  • 14
8

You can generate arrays with 10 random numbers just two lines of code.

let result = new Array(10)
result = result.fill(0).map(() => Math.random());

and just .

console.log(vals);
thegreytangent
  • 316
  • 2
  • 12
5

Using some new ES6 features, this can now be achieved using:

function getRandomInt(min, max) {
    "use strict";
    if (max < min) {
        // Swap min and max
        [min, max] = [min, max];
    }

    // Generate random number n, where min <= n <= max
    let range = max - min + 1;
    return Math.floor(Math.random() * range) + min;
}

let values = Array.from({length: 40}, () => getRandomInt(0, 40));

console.log(values);

Note that this solution will only work in modern browsers that support these ES6 features: arrow functions and Array.from().

Lachlan Hunt
  • 2,770
  • 1
  • 17
  • 7
5

Since the range of numbers is constrained, I'd say the best thing to do is generate the array, fill it with numbers zero through 39 (in order), then shuffle it.

Pointy
  • 405,095
  • 59
  • 585
  • 614
  • Here's [a visualization of this technique](http://phrogz.net/tmp/7x7_random.html) (although that page uses [a **terrible** shuffle algorithm](http://phrogz.net/JS/JavaScript_Random_Array_Sort.html)). – Phrogz Apr 29 '11 at 20:09
  • I don't know that he wanted every number between, but rather completely random? If he's fine with random order, static values then this will work fine. – Robert Apr 29 '11 at 20:10
  • which might do the job, but will give slightly different results than if you used `Math.random()` 40 times, since it will enforce each number appearing once and no repeats. – Mu Mind Apr 29 '11 at 20:13
3

Quirk single-line solutions on every day.

Values in arrays is total random, so when you will be use this snippets, it will different.

An array (length 10) with random chars in lowercase

Array.apply(null, Array(10)).map(function() { return String.fromCharCode(Math.floor(Math.random() * (123 - 97) + 97)); })

[ 'k', 'a', 'x', 'y', 'n', 'w', 'm', 'q', 'b', 'j' ]

An array (length 10) with random integer numbers from 0 to 99

Array.apply(null, Array(10)).map(function() { return Math.floor(Math.random() * 100 % 100); })

[ 86, 77, 83, 27, 79, 96, 67, 75, 52, 21 ]

An array random dates (from 10 years to ago to now)

Array.apply(null, Array(10)).map(function() { return new Date((new Date()).getFullYear() - Math.floor(Math.random() * 10), Math.floor(Math.random() * 12), Math.floor(Math.random() * 29) )})

[ 2008-08-22T21:00:00.000Z, 2007-07-17T21:00:00.000Z,
2015-05-05T21:00:00.000Z, 2011-06-14T21:00:00.000Z,
2009-07-23T21:00:00.000Z, 2009-11-13T22:00:00.000Z,
2010-05-09T21:00:00.000Z, 2008-01-05T22:00:00.000Z,
2016-05-06T21:00:00.000Z, 2014-08-06T21:00:00.000Z ]

An array (length 10) random strings

Array.apply(null, Array(10)).map(function() { return Array.apply(null, Array(Math.floor(Math.random() * 10  + 3))).map(function() { return String.fromCharCode(Math.floor(Math.random() * (123 - 97) + 97)); }).join('') });

[ 'cubjjhaph', 'bmwy', 'alhobd', 'ceud', 'tnyullyn', 'vpkdflarhnf', 'hvg', 'arazuln', 'jzz', 'cyx' ]

Other useful things you may found here https://github.com/setivolkylany/nodejs-utils/blob/master/utils/faker.js

PADYMKO
  • 4,217
  • 2
  • 36
  • 41
3
var myArray = [];
var arrayMax = 40;
var limit = arrayMax + 1;
for (var i = 0; i < arrayMax; i++) {
  myArray.push(Math.floor(Math.random()*limit));
}

This above is the traditional way of doing it but I second @Pointy and @Phrogz if you want to avoid duplicates in your array without having to do expensive computation

Ady Ngom
  • 1,284
  • 2
  • 10
  • 12
2

Using Es6

Option 1

new Array(40).fill(0).map(_ => Math.random() * 40 | 0)

creating an empty array of length 40,then filling it with 0 and then replacing zeros with random number. Math.random() generates floating number,so to float to int,using Bitwise OR(|)

Option 2

[...Array(40)].map(_ => Math.random() * 40 | 0)

replaced new Array(40).fill(0) with [...Array(40)] - it will clone empty(undefined) array of length 40

Option 3

using Array.from

Array.from(arrayLike, mapFn)

arrayLike

An array-like or iterable object to convert to an array.

mapFn (Optional)

Map function to call on every element of the array.

Array.from({length: 10}, () => Math.floor(Math.random() * 100));

If you want to fill with UNIQUE random numbers

We will achieve this using Set,as we know set only allows to add unique values.

let set = new Set();
while (set.size <= 40) {
  set.add((Math.random() * 400) | 0);
}
let randomArray = [...set];

But here one thing is important,that you need to multiply with bigger number than array length...otherwise it will take too much time to generate unique number,it might freeze the execution for long time.try to take 10 times bigger number as I take here 400

Saptarsi
  • 796
  • 5
  • 13
1
function shuffle(maxElements) {
    //create ordered array : 0,1,2,3..maxElements
    for (var temArr = [], i = 0; i < maxElements; i++) {
        temArr[i] = i;
    }

    for (var finalArr = [maxElements], i = 0; i < maxElements; i++) {
        //remove rundom element form the temArr and push it into finalArrr
        finalArr[i] = temArr.splice(Math.floor(Math.random() * (maxElements - i)), 1)[0];
    }

    return finalArr
}

I guess this method will solve the issue with the probabilities, only limited by random numbers generator.

1

I am pretty sure that this is the shortest way to create your random array without any repeats

var random_array = new Array(40).fill().map((a, i) => a = i).sort(() => Math.random() - 0.5);
Jamie337nichols
  • 157
  • 1
  • 11
  • "pretty sure", how about using the `keys` function: `Array.from(Array(40).keys()).sort(_ => Math.random() - .5)`? You might even go crazy, and use the spread operator! But that is too exciting for me right now. – Yeti Aug 01 '20 at 07:13
1

Refer below :-

let arr = Array.apply(null, {length: 1000}).map(Function.call, Math.random)
/* will create array with 1000 elements */
Avadhut Thorat
  • 997
  • 11
  • 7
0

I needed something a bit different than what these solutions gave, in that I needed to create an array with a number of distinct random numbers held to a specified range. Below is my solution.

function getDistinctRandomIntForArray(array, range){
   var n = Math.floor((Math.random() * range));
   if(array.indexOf(n) == -1){        
    return n; 
   } else {
    return getDistinctRandomIntForArray(array, range); 
   }
}

function generateArrayOfRandomInts(count, range) {
   var array = []; 
   for (i=0; i<count; ++i){
    array[i] = getDistinctRandomIntForArray(array, range);
   };
   return array; 
}

I would have preferred to not create a loop that has the possibility to end up with a lot of unnecessary calls (if your count, and range are high and are close to the same number) but this is the best I could come up with.

Joe
  • 185
  • 2
  • 4
0

If you need it with random unique values from 0...length range:

const randomRange = length => {
  const results = []
  const possibleValues = Array.from({ length }, (value, i) => i)

  for (let i = 0; i < length; i += 1) {
    const possibleValuesRange = length - (length - possibleValues.length)
    const randomNumber = Math.floor(Math.random() * possibleValuesRange)
    const normalizedRandomNumber = randomNumber !== possibleValuesRange ? randomNumber : possibleValuesRange

    const [nextNumber] = possibleValues.splice(normalizedRandomNumber, 1)

    results.push(nextNumber)
  }

  return results
}

randomRange(5) // [3, 0, 1, 4, 2]
0

from the page suggested by @Phrogz

for (var i=0,nums=[];i<49;i++) nums[i]={ n:i, rand:Math.random() };
nums.sort( function(a,b){ a=a.rand; b=b.rand; return a<b?-1:a>b?1:0 } );
Saic Siquot
  • 6,513
  • 5
  • 34
  • 56
0

A little late to the party, but I use randojs.com for randomness because it makes stuff like this super easy. You can get a randomly shuffled array of numbers from 0 through 39 just like this:

console.log(randoSequence(40));
<script src="https://randojs.com/1.0.0.js"></script>

No fuss with the logistics of it all- plus it's super readable and easy to understand :)

Community
  • 1
  • 1
Aaron Plocharczyk
  • 2,776
  • 2
  • 7
  • 15
0

Generators

An array of length 40 of 40 random possible values (0 - 39) without repeating values is better to shuffle it as @Phrogz and @Jared Beck explain. Another approach, just for the records, could be using generators. But this approach lacks of performance compared to other proposed solutions.

function* generateRandomIterable(n, range) {
  for (let i = 0; i < n; i++) {
    yield ~~(Math.random() * range);
  }
}
const randomArr = [...generateRandomIterable(40,40)];
brbn
  • 71
  • 4
0

Here is a ES6 function that allows a min and a max and will generate an array of unique values in random order that contain all the number from min to max inclusive:

const createRandomNumbers = (min, max) => {
  const randomNumbers = new Set()
  const range = max - min + 1

  while (randomNumbers.size < range) {
    randomNumbers.add(~~(Math.random() * range))
  }

  return [...randomNumbers]
}
Curt
  • 794
  • 7
  • 8
  • Nice use of Set() to keep it unique, but: (1) Need to add "+min" in the add() and (2) if the range is large, the loop would iterate more and more as it fills the array, and maybe for a very long time on the final numbers. – royappa Feb 11 '21 at 02:59