Sarah
Sarah

Reputation: 13051

Getting a random value from a JavaScript array

Consider:

var myArray = ['January', 'February', 'March'];    

How can I select a random value from this array using JavaScript?

Upvotes: 1286

Views: 1141547

Answers (18)

Kamil Kiełczewski
Kamil Kiełczewski

Reputation: 92347

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) )

Additional info from mdn:

Note: Math.random() does not provide cryptographically secure random numbers. Do not use them for anything related to security. Use the Web Crypto API instead, and more precisely the Crypto.getRandomValues() method.

Upvotes: 5

Utopiah
Utopiah

Reputation: 324

MyArray.at(MyArray.length*Math.random())

I find this both concise and clear. Requires ES2022.

Upvotes: 1

Dhakshith
Dhakshith

Reputation: 64

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();

Upvotes: 1

Tony O'Hagan
Tony O'Hagan

Reputation: 22672

Many of the offered solutions add a method to a specific Array which restricts it's use to just that array. This solution is reusable code that works for any array and can be made type safe.

TypeScript

export function randChoice<T>(arr: Array<T>): T {
  return arr[Math.floor(Math.random() * arr.length)]
}

JavaScript

function randChoice(arr) {
  return arr[Math.floor(Math.random() * arr.length)]
}

Upvotes: 18

Nathan
Nathan

Reputation: 5329

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.helpers.arrayElement(['January', 'February', 'March']);

As commenters have mentioned, you generally should not use this library in production code.

Upvotes: 9

CrazyTim
CrazyTim

Reputation: 7316

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.

Upvotes: 23

Manngo
Manngo

Reputation: 16281

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;

Upvotes: 6

foxiris
foxiris

Reputation: 3378

The shortest version:

var myArray = ['January', 'February', 'March']; 
var rand = myArray[(Math.random() * myArray.length) | 0]
console.log(rand)

Upvotes: 45

Ben Aubin
Ben Aubin

Reputation: 5657

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.

Upvotes: 62

Ankur Soni
Ankur Soni

Reputation: 6008

~~ 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

Upvotes: 52

Jacob Relkin
Jacob Relkin

Reputation: 163228

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]);

Upvotes: 2336

Kamuran S&#246;necek
Kamuran S&#246;necek

Reputation: 3334

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<n;i++){
      a.push(this[Math.floor(Math.random()*this.length)]);
    }
    return a;
  } else {
    return this[Math.floor(Math.random()*this.length)];
  }
}

const mySampleArray =  ['a','b','c','d','e','f','g','h'];

mySampleArray.random(); // return any random value etc. 'a', 'b'
mySampleArray.random(3); //retun an array with random values etc: ['b','f','a'] , ['d','b','d']

alert(mySampleArray.random());
alert(mySampleArray.random(3));

Upvotes: -1

Seagull
Seagull

Reputation: 3600

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);

Upvotes: 8

dwilt
dwilt

Reputation: 625

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])
}

Upvotes: 3

Pavel P
Pavel P

Reputation: 16843

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);

Upvotes: 1

Brendan Nee
Brendan Nee

Reputation: 5353

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);

Upvotes: 137

Max Heiber
Max Heiber

Reputation: 15492

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.

Upvotes: 1

I.G. Pascual
I.G. Pascual

Reputation: 5965

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?

Upvotes: 12

Related Questions