Consider:
var myArray = ['January', 'February', 'March'];
How can I select a random value from this array using JavaScript?
It's a simple one-liner:
const randomElement = array[Math.floor(Math.random() * array.length)];
For example:
const months = ["January", "February", "March", "April", "May", "June", "July"]; const random = Math.floor(Math.random() * months.length); console.log(random, months[random]);
If you've already got underscore or lodash included in your project you can use _.sample
.
// will return one item randomly from the array
_.sample(['January', 'February', 'March']);
If you need to get more than one item randomly, you can pass that as a second argument in underscore:
// will return two items randomly from the array using underscore
_.sample(['January', 'February', 'March'], 2);
or use the _.sampleSize
method in lodash:
// will return two items randomly from the array using lodash
_.sampleSize(['January', 'February', 'March'], 2);
You may consider defining a function on the Array prototype, in order to create a method [].sample()
which returns a random element.
First, to define the prototype function, place this snippet in your code:
Array.prototype.sample = function(){
return this[Math.floor(Math.random()*this.length)];
}
Later, to sample a random element from the array, just call .sample()
:
[1,2,3,4].sample() //=> a random element
I'm releasing these code snippets into the public domain, under the terms of the CC0 1.0 license.
.sample()
on any array to get a random item
~~
is much faster than Math.Floor()
, so when it comes to performance optimization while producing output using UI elements, ~~
wins the game. MORE INFO
var rand = myArray[~~(Math.random() * myArray.length)];
But if you know that the array is going to have millions of elements then you might want to reconsider between Bitwise Operator and Math.Floor()
, as bitwise operators behave weirdly with large numbers. See below example explained with the output.
var number = Math.floor(14444323231.2); // => 14444323231
var number = 14444323231.2 | 0; // => 1559421343
Math.floor
now :)
~
is a bitwise not
, which reverses the 1
s and 0
s in a binary number. As with all bitwise operators, it first converts the number into a 32 bit integer, which all you really want. Using ~~
restores the original as a 32-bit integer.
Math.floor()
, All functions have an overhead which includes storing and restoring the original state. Generally, optimising compilers will look for opportunities to copy the code in place to avoid that overhead, but, with a dynamic language such as JavaScript, it’s harder to predict.
The shortest version:
var myArray = ['January', 'February', 'March']; var rand = myArray[(Math.random() * myArray.length) | 0] console.log(rand)
| 0
do?
| 0
itself is a bitwise operation that does nothing, but in javascript floats are converted to ints before any bitwise operation. So it's something like how + ''
doesn't really do anything but can be used to convert things to strings.
Math.floor
but it is the correct thing to do here. It's an operator so it's faster than Math.floor
if only because at any time while running some code can do Math.floor = someOtherFunction
and they can't do the same for '|'. On the other hand as for Math.floor
and |
being different try Math.floor(-1.5)
vs -1.5 | 0
. By the way you don't need the parentheses. |
has a very low precedence.
Say you want to choose a random item that is different from the last time (not really random, but still a common requirement)...
/**
* Return a random element from an array that is
* different than `last` (as long as the array has > 1 items).
* Return null if the array is empty.
*/
function getRandomDifferent(arr, last = undefined) {
if (arr.length === 0) {
return null;
} else if (arr.length === 1) {
return arr[0];
} else {
let num = 0;
do {
num = Math.floor(Math.random() * arr.length);
} while (arr[num] === last);
return arr[num];
}
}
Implement like this:
const arr = [1,2,3];
const r1 = getRandomDifferent(arr);
const r2 = getRandomDifferent(arr, r1); // r2 is different than r1.
If you have fixed values (like a month name list) and want a one-line solution
var result = ['January', 'February', 'March'][Math.floor(Math.random() * 3)]
The second part of the array is an access operation as described in Why does [5,6,8,7][1,2] = 8 in JavaScript?
If you want to write it on one line, like Pascual's solution, another solution would be to write it using ES6's find function (based on the fact, that the probability of randomly selecting one out of n
items is 1/n
):
var item = ['A', 'B', 'C', 'D'].find((_, i, ar) => Math.random() < 1 / (ar.length - i)); console.log(item);
Use that approach for testing purposes and if there is a good reason to not save the array in a seperate variable only. Otherwise the other answers (floor(random()*length
and using a seperate function) are your way to go.
Faker.js has many utility functions for generating random test data. It is a good option in the context of a test suite:
const Faker = require('faker');
Faker.random.arrayElement(['January', 'February', 'March']);
As commenters have mentioned, you generally should not use this library in production code.
Faker
which selects a random array element.
If you need to fetch a random item more than once, then, obviously you would use a function. One way is to make that function a method of the Array.prototype
, but that will normally get you shouted down for tampering with built in prototypes.
However, you can add the method to the specific array itself:
var months = ['January', 'February', 'March'];
months.random = function() {
return this[Math.floor(Math.random()*this.length)];
};
That way you can use months.random()
as often as you like without interfering with the generic Array.prototype
.
As with any random function, you run the risk of getting the same value successively. If you don’t want that, you will need to track the previous value with another property:
months.random=function() {
var random;
while((random=this[Math.floor(Math.random()*this.length)]) == this.previous);
this.previous=random;
return random;
};
If you’re going to do this sort of thing often, and you don’t want to tamper with Array.prototype
, you can do something like this:
function randomValue() {
return this[Math.floor(Math.random()*this.length)];
}
var data = [ … ];
var moreData = [ … ];
data.random=randomValue;
moreData.random=randomValue;
Editing Array prototype can be harmful. Here it is a simple function to do the job.
function getArrayRandomElement (arr) {
if (arr && arr.length) {
return arr[Math.floor(Math.random() * arr.length)];
}
// The undefined will be returned if the empty array was passed
}
Usage:
// Example 1
var item = getArrayRandomElement(['January', 'February', 'March']);
// Example 2
var myArray = ['January', 'February', 'March'];
var item = getArrayRandomElement(myArray);
To get crypto-strong random item form array use
let rndItem = a=> a[rnd()*a.length|0]; let rnd = ()=> crypto.getRandomValues(new Uint32Array(1))[0]/2**32; var myArray = ['January', 'February', 'March']; console.log( rndItem(myArray) )
Recursive, standalone function which can return any number of items (identical to lodash.sampleSize):
function getRandomElementsFromArray(array, numberOfRandomElementsToExtract = 1) {
const elements = [];
function getRandomElement(arr) {
if (elements.length < numberOfRandomElementsToExtract) {
const index = Math.floor(Math.random() * arr.length)
const element = arr.splice(index, 1)[0];
elements.push(element)
return getRandomElement(arr)
} else {
return elements
}
}
return getRandomElement([...array])
}
This is similar to, but more general than, @Jacob Relkin's solution:
This is ES2015:
const randomChoice = arr => {
const randIndex = Math.floor(Math.random() * arr.length);
return arr[randIndex];
};
The code works by selecting a random number between 0 and the length of the array, then returning the item at that index.
var item = myArray[Math.floor(Math.random()*myArray.length)];
or equivalent shorter version:
var item = myArray[(Math.random()*myArray.length)|0];
Sample code:
var myArray = ['January', 'February', 'March']; var item = myArray[(Math.random()*myArray.length)|0]; console.log('item:', item);
Simple Function :
var myArray = ['January', 'February', 'March'];
function random(array) {
return array[Math.floor(Math.random() * array.length)]
}
random(myArray);
OR
var myArray = ['January', 'February', 'March'];
function random() {
return myArray[Math.floor(Math.random() * myArray.length)]
}
random();
OR
var myArray = ['January', 'February', 'March'];
function random() {
return myArray[Math.floor(Math.random() * myArray.length)]
}
random();
In my opinion, better than messing around with prototypes , or declaring it just in time, I prefer exposing it to window:
window.choice = function() {
if (!this.length || this.length == 0) return;
if (this.length == 1) return this[0];
return this[Math.floor(Math.random()*this.length)];
}
Now anywhere on your app you call it like:
var rand = window.choice.call(array)
This way you can still use for(x in array)
loop properly
for...in
on arrays, or even in general. You run the risk of walking the prototype chain. It's also meant for all properties of an object, not all indices in an array. If you want to use an iterator on an array, use for (var i = 0; i < foo.length; i++){}
. Even better, use something like Array.prototype.forEach
instead.
I've found a way around the top answer's complications, just by concatenating the variable rand to another variable that allows that number to be displayed inside the calling of myArray[];. By deleting the new array created and toying around with it's complications, I've come up with a working solution:
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script>
var myArray = ['January', 'February', 'March', 'April', 'May'];
var rand = Math.floor(Math.random() * myArray.length);
var concat = myArray[rand];
function random() {
document.getElementById("demo").innerHTML = (concat);
}
</script>
<button onClick="random();">
Working Random Array generator
</button>
</body>
</html>
concat
is ever changing here... random
itself isn't changing it, and nothing else is getting called more than once....
static generateMonth() { const theDate = ['January', 'February', 'March']; const randomNumber = Math.floor(Math.random()*3); return theDate[randomNumber]; };
You set a constant variable to the array, you then have another constant that chooses randomly between the three objects in the array and then the function simply returns the results.
Looking for a true one-liner I came to this:
['January', 'February', 'March'].reduce((a, c, i, o) => { return o[Math.floor(Math.random() * Math.floor(o.length))]; })
By adding a method on prototype of array you can get random values easly.
In this example you can get single or multiple random values from array.
You can run to test code by clicking snippet button.
Array.prototype.random = function(n){
if(n&&n>1){
const a = [];
for(let i = 0;i
Method 1:
Use Math.random() function to get the random number between(0-1, 1 exclusive).
Multiply it by the array length to get the numbers between(0-arrayLength).
Use Math.floor() to get the index ranging from(0 to arrayLength-1).
const arr = ["foo","bar"]; const randomlyPickedString=arr[Math.floor(Math.random() * arr.length)]; console.log(randomlyPickedString);
Method 2:
The random(a, b) method is used to generates a number between(a to b, b exclusive).
Taking the floor value to range the numbers from (1 to arrayLength).
Subtract 1 to get the index ranging from(0 to arrayLength-1).
const arr = ["foo","bar"]; const randomlyPickedString=arr[Math.floor(random(1, 5))-1]; console.log(randomlyPickedString);
A generic way to get random element(s):
let some_array = ['Jan', 'Feb', 'Mar', 'Apr', 'May']; let months = random_elems(some_array, 3); console.log(months); function random_elems(arr, count) { let len = arr.length; let lookup = {}; let tmp = []; if (count > len) count = len; for (let i = 0; i < count; i++) { let index; do { index = ~~(Math.random() * len); } while (index in lookup); lookup[index] = null; tmp.push(arr[index]); } return tmp; }
Here is an example of how to do it:
$scope.ctx.skills = data.result.skills;
$scope.praiseTextArray = [
"Hooray",
"You\'re ready to move to a new skill",
"Yahoo! You completed a problem",
"You\'re doing great",
"You succeeded",
"That was a brave effort trying new problems",
"Your brain was working hard",
"All your hard work is paying off",
"Very nice job!, Let\'s see what you can do next",
"Well done",
"That was excellent work",
"Awesome job",
"You must feel good about doing such a great job",
"Right on",
"Great thinking",
"Wonderful work",
"You were right on top of that one",
"Beautiful job",
"Way to go",
"Sensational effort"
];
$scope.praiseTextWord = $scope.praiseTextArray[Math.floor(Math.random()*$scope.praiseTextArray.length)];
Create one random value and pass to array
Please try following code..
//For Search textbox random value
var myPlaceHolderArray = ['Hotels in New York...', 'Hotels in San Francisco...', 'Hotels Near Disney World...', 'Hotels in Atlanta...'];
var rand = Math.floor(Math.random() * myPlaceHolderArray.length);
var Placeholdervalue = myPlaceHolderArray[rand];
alert(Placeholdervalue);
randojs makes this a little more simple and readable:
console.log( rando(['January', 'February', 'March']).value );
I am really surprised nobody tried to use native random values:
array[Date.now()%array.length]
It will not work for array length over 160000000000, but I am sure you will never create arrays like this
UPD
As far as you question is how to pick random value from array called myArray
(with len=3), the solution should be:
myArray[Date.now()%myArray.length]
Date.now()
has nothing to do with randomness and is quite deterministic indeed. I get that it might feel "random" enough in some use-cases though
Date.now()
everytime returns different values, this way it cannot be detemined for 100% accurace, moreover in case for array about 3 elements.
Math.Rand
implemented solutions, as far as it is one pseudo-random function
Success story sharing
Math.floor(Math.random(...))
call, which rounds down.var rand = myArray[Math.random() * myArray.length>>0]
being slightly fastervar rand = myArray[Math.random() * myArray.length | 0]
Math.floor
instead ofMath.trunc
?