26

Following up on this answer for creating an array of specified length, I executed the below to get a corresponding result but filled with random numbers, instead of zeros.

var randoms = Array(4).fill(Math.floor(Math.random() * 9));

Well, mathematically speaking it's random, all right. But I'd like the randomness to be visible within the array and not only between runs, of course. Stupid computer... Don't do what I say. Do what I want!

I can iterate and put it my random (and varying) values. But I wonder, of pure curiosity, if it's possible to get the right result with a one-liner, like above, MatLab-style. Do I need to call eval(function()...)? I've heard a lot of bad things about eval...

Note that the above produces code like this:

[7, 7, 7, 7]
[3, 3, 3, 3]

etc. while I want something like

[1, 2, 3, 4]
[4, 3, 8, 4]

Community
  • 1
  • 1
Konrad Viltersten
  • 36,151
  • 76
  • 250
  • 438
  • I don't understand _But I'd like the randomness to be visible within the array and not only between runs, of course_. AFAIU, you just want to create an array of length `n` with random numbers. – Tushar Jan 23 '16 at 17:23
  • @Tushar If you run the line in the console, you'll see... It creates **a single** random number and copies it in on all places as a fix number. First when you run again, you'll get a set of other numbers (all the same for each run). Easy to miss, huh? I've updated the question. Thanks. – Konrad Viltersten Jan 23 '16 at 17:26
  • "The fill() method fills all the elements of an array from a start index to an end index with a static [sic!] value." [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill) – Nina Scholz Jan 23 '16 at 17:31
  • 1
    @NinaScholz Yeah, that's what I recognized. It's a random value. True that. But not what I wanted. I recall a teacher claiming that there's no function for generating only prime numbers. I contradicted him by *function(){ return 13; }* He wasn't happy. Everybody else was amused. – Konrad Viltersten Jan 23 '16 at 17:35

6 Answers6

29

What does Array#fill do?

According to MDN

The fill() method fills all the elements of an array from a start index to an end index with a static value.

You can use Function#apply, Array#map, Math.floor(), Math.random().

In ES6, Array#from and Arrow function can be used.

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

Array.apply(null, Array(6)).map(() => Math.floor(Math.random() * 9));

var randomArr = Array.from({length: 6}, () => Math.floor(Math.random() * 9));

document.getElementById('result').innerHTML = JSON.stringify(randomArr, 0, 4); // For demo only
<pre id="result"></pre>

In ES5:

Array.apply(null, Array(6)).map(function(item, index){
    return Math.floor(Math.random() * 9);
});

var randomArr = Array.apply(null, Array(6)).map(function(item, index){
    return Math.floor(Math.random() * 9)
});

document.getElementById('result').innerHTML = JSON.stringify(randomArr, 0, 4);
<pre id="result"></pre>

What is Array.apply(null, Array(n))? Can new Array(n) used here?

Both the above code create new array of six elements, each element having value as undefined. However, when used new syntax, the created array is not iterable. To make the array iterable, Array.apply(null, Array(6)) syntax is used.


If you have lodash included on page, it's really easy.

_.times(6, _.random.bind(0, 100))
        ^                        - Number of elements in array
                         ^       - Random number range min
                            ^^^  - Random number range max

Note: This answer is inspired from Colin Toh's blog

Tushar
  • 85,780
  • 21
  • 159
  • 179
15

I wonder if it's possible to get the right result with a one-liner...

var randoms = [...Array(4)].map(() => Math.floor(Math.random() * 9));

document.body.innerText = randoms;
vsync
  • 118,978
  • 58
  • 307
  • 400
7vujy0f0hy
  • 8,741
  • 1
  • 28
  • 33
6
var randoms = Array(4).fill(Math.floor(Math.random() * 9));

This line of code will create a list of 4 of the same number because fill takes a single value and repeats it for the length of the list. What you want to do is run the random number generator each time:

var makeARandomNumber = function(){
    return Math.floor(Math.random() * 9);
}
var randoms = Array(5).fill(0).map(makeARandomNumber);
console.log(randoms)
// => [4, 4, 3, 2, 6]

https://jsfiddle.net/t4jtjcde/

Conrad.Dean
  • 4,341
  • 3
  • 32
  • 41
  • Yeah, I got that. I'm just unsure why @Tushar used *apply()* in there. It seems that I get the same result without it but I'm cautious enough to know that there might be dragons here and there. Also, I wonder why you're using the zero argument in *fill()*. I seem to be getting the same results without it (trying both *fill(null)* and simply *fill()*). Is it a better style? Does it prevent something down the road? – Konrad Viltersten Jan 24 '16 at 14:40
  • re fill(0), just wanted to give it something, no real plan there. re Tushar's use of apply(), they mention that they do that to make the array iterable. I haven't played with it to test that behavior out, but not all objects respond to javascript's built-in looping constructs the way you'd expect because sometimes something look like an array when really it's an object with index properties. i choose to ignore these details and just use lodash for everything – Conrad.Dean Jan 25 '16 at 15:05
5

Short and simple ES6 approach -

// randomly generated n = 4 length array 0 <= array[n] <= 9
var randoms = Array.from({length: 4}, () => Math.floor(Math.random() * 10));

Enjoy!

Simon Borsky
  • 4,979
  • 2
  • 22
  • 20
  • What exactly is {length: 4} here? A search only pulls up the String length property, `.length`, which I believe is a different construction. – jtr13 Mar 31 '18 at 14:45
  • 1
    If as a first parameter we provide an object contained length property the Array.from() knows that it can generate a sequence of numbers. Read about it here - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from – Simon Borsky Apr 02 '18 at 17:55
0

`const t = Array.from({length: n}, mapArrowFx);

1) const t10 = Array.from({length: 10}, (v, k) => k); [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

2) const tEven = Array.from({length: 10}, (v, k) => 2*k); [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

........

3)

let n=100; const tRandom= Array.from({length: n}, (v, k) => Math.floor(Math.random()*n));

...

Community
  • 1
  • 1
0

Solution from Sized array of random unique numbers

const uniqRandomNumbers  = _.sampleSize(_.range(9), 4);
console.log(uniqRandomNumbers);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>
Rami Chasygov
  • 2,714
  • 7
  • 25
  • 37