1533
var items = Array(523, 3452, 334, 31, ..., 5346);

How do I get random item from items?

5
  • 439
    the answer will not involve jQuery Commented May 6, 2011 at 17:51
  • 57
    I've never seen so many absolutely identical responses to a question... Commented May 6, 2011 at 17:52
  • 14
    This question is absolutely identical to Getting random value from an array, yet the Mighty Mods haven't bothered to close it in 3+ years. Instead, they close "unconstructive" questions with hundreds of votes. Commented Dec 16, 2014 at 11:01
  • All answers to this problem are fundamentally wrong from what I can see and each basically just copy the others. What happens if the array has had elements deleted ([0],[1],[3],[4]...)? What happens if elements are added in way that keys are not an consistently incremented value but instead have some other meaning (such as a unique user id ([3453],[4316],[73698],[924]...). Are people so stuck on how to correctly use Math.random() that they are overlooking this? Commented Sep 6, 2018 at 4:35
  • 1
    @JSON Why would you ever delete random values in the array or use an array with "keys" being something other than a "consistently incremented value"? That's the whole point of arrays, they're indexable from 0 to the length - 1, and I've never seen one that wasn't. Consider contributing your own answer if you have a novel solution to whatever problem you perceive with the existing answers. Commented Jul 7, 2024 at 15:55

13 Answers 13

3154
var item = items[Math.floor(Math.random()*items.length)];
Sign up to request clarification or add additional context in comments.

11 Comments

Math.random() will never be 1, nor should it. The largest index should always be one less than the length, or else you'll get an undefined error.
Elegant solution. I tested it: var items = ["a","e","i","o","u"] var objResults = {} for(var i = 0; i < 1000000; i++){ var randomElement = items[Math.floor(Math.random()*items.length)] if (objResults[randomElement]){ objResults[randomElement]++ }else{ objResults[randomElement] = 1 } } console.log(objResults) The results are pretty randomized after 1000000 iterations: Object {u: 200222, o: 199543, a: 199936, e: 200183, i: 200116}
@virus Math.round is not a valid substitution for Math.floor. Using round would cause accidentally referencing an undefined index, say in the case Math.random() is 0.95 and items.length is 5. Math.round(0.95*5) is 5, which would be an invalid index. floor(random) will always be zero in your example.
Nice answer. You can be shorter: items[items.length * Math.random() | 0] :)
@aloisdg that's true, as long as the array length is less than 2^31, which is still a very large number :)
|
168

1. solution: define Array prototype

Array.prototype.random = function () {
  return this[Math.floor((Math.random()*this.length))];
}

that will work on inline arrays

[2,3,5].random()

and of course predefined arrays

var list = [2,3,5]
list.random()

2. solution: define custom function that accepts list and returns element

function get_random (list) {
  return list[Math.floor((Math.random()*list.length))];
}


get_random([2,3,5])

7 Comments

@EvanCarroll better reference a useful link instead of downvoting for subjective notions such as coding style which does not make the answer invalid nor "unuseful" ! stackoverflow.com/questions/14034180/…
Upvoted because downvoting for adding something to Array.prototype is not useful to anyone without explanation.
The issue with adding a new function to Array.prototype is the same issue as adding a global variable - someone/something else may be using the same "name" for something different - which can cause subtle mahem
Thank you for this. Far more usable than typing the whole vanilla formula or calling a custom function when the code requires it more than once. As for the valid concerns about conflicts, that's what namespacing is for: ns. or ns_ format where applicable.
@Schmoo I just ran into one of those "subtle mayhem" situations. I shortened the prototype's name to "rand". Then suddenly during a for (let i in arr) loop, it iterates all the expected indexes, and also iterates an index of "rand". Had to switch to a for (let i=0,l=arr.length;i<l;i++) loop to fix it.
|
133

Use underscore (or loDash :)):

var randomArray = [
   '#cc0000','#00cc00', '#0000cc'
];

// use _.sample
var randomElement = _.sample(randomArray);

// manually use _.random
var randomElement = randomArray[_.random(randomArray.length-1)];

Or to shuffle an entire array:

// use underscore's shuffle function
var firstRandomElement = _.shuffle(randomArray)[0];

9 Comments

Using underscore or lodash for just one function would be overkill, but if you're doing any complicated js functionality then it can save hours or even days.
Nowadays underscore has also better choice for this _.sample([1, 2, 3, 4, 5, 6])
You will probably be using _ on any real project. It's not a bad thing.
lodash is modularized on npm, so you can install just the sample function if you want: npmjs.com/package/lodash.sample
My creed is to use as few libraries as possible for any project. With that being said, I always end up using lodash. It's too convenient to not use
|
111

If you really must use jQuery to solve this problem (NB: you shouldn't, but the original version of the question asked for jQuery solutions):

(function($) {
    $.rand = function(arg) {
        if ($.isArray(arg)) {
            return arg[$.rand(arg.length)];
        } else if (typeof arg === "number") {
            return Math.floor(Math.random() * arg);
        } else {
            return 4;  // chosen by fair dice roll
        }
    };
})(jQuery);

var items = [523, 3452, 334, 31, ..., 5346];
var item = jQuery.rand(items);

This plugin will return a random element if given an array, or a value from [0 .. n) given a number, or given anything else, a guaranteed random value!

For extra fun, the array return is generated by calling the function recursively based on the array's length :)

Working demo at http://jsfiddle.net/2eyQX/

8 Comments

@neoascetic the point of that line is that picking an element from an array is not a jQuery problem, it's generic JS.
Definitely. There are less than an average of 3 chained methods per line, and the $ is not being used at least once per each line, therefore it does not have enough jQuery.
This is not a problem that requires jQuery.
|
79

Here's yet another way:

function rand(items) {
    // "~~" for a closest "int"
    return items[~~(items.length * Math.random())];
}

Or as recommended below by @1248177:

function rand(items) {
    // "|" for a kinda "int div"
    return items[items.length * Math.random() | 0];
}

9 Comments

What is that crazy ~~? Never seen that in JS before.
@hatboysam: do a search - it essentially converts the operand to the closest integer.
Actually, it rounds it down, like Math.floor.
Nice answer. You still can be shorter: items[items.length * Math.random() | 0] :)
"Actually, it rounds it down, like Math.floor" @programmer5000. It actually rounds towards 0, i.e. ~~(-1.5) evaluates to -1, not the -2 which Math.floor gives.
|
57
var random = items[Math.floor(Math.random()*items.length)]

1 Comment

Already posted dozens of times before. Suggest deletion.
27
// 1. Random shuffle items
items.sort(function() {return 0.5 - Math.random()})

// 2. Get first item
var item = items[0]

Shorter:

var item = items.sort(function() {return 0.5 - Math.random()})[0];

Even shoter (by José dB.):

let item = items.sort(() => 0.5 - Math.random())[0];

6 Comments

items[1] is the second item, the first is items[0].
Oh, sorry. Of coz items[0]
This does not give you a uniform shuffle: sroucheray.org/blog/2009/11/…
Next shoter: let item = items.sort(() => 0.5 - Math.random())[0];
Would be also good to know the complexity of thar algorithm :)
|
23

jQuery is JavaScript! It's just a JavaScript framework. So to find a random item, just use plain old JavaScript, for example,

var randomItem = items[Math.floor(Math.random()*items.length)]

1 Comment

Already posted dozens of times before. Suggest deletion.
19
var rndval=items[Math.floor(Math.random()*items.length)];

1 Comment

Already posted dozens of times before. Suggest deletion.
9
var items = Array(523,3452,334,31,...5346);

function rand(min, max) {
  var offset = min;
  var range = (max - min) + 1;

  var randomNumber = Math.floor( Math.random() * range) + offset;
  return randomNumber;
}


randomNumber = rand(0, items.length - 1);

randomItem = items[randomNumber];

credit:

Javascript Function: Random Number Generator

1 Comment

FYI, this could be one lined: Math.floor(Math.random() * (max - min + 1)) + min
6

If you are using node.js, you can use unique-random-array. It simply picks something random from an array.

1 Comment

Don't use a third party lib for this simple operation.
1

An alternate way would be to add a method to the Array prototype:

 Array.prototype.random = function (length) {
       return this[Math.floor((Math.random()*length))];
 }

 var teams = ['patriots', 'colts', 'jets', 'texans', 'ravens', 'broncos']
 var chosen_team = teams.random(teams.length)
 alert(chosen_team)

3 Comments

arrays have a built-in length property - why pass it as a parameter?!
i guess my point is that you can pass in any length you want not just the length of the array - if you just wanted to randomize the first two entries you could put length as 2 without changing the method. I don't think there is a performance issue with passing the length property as a parameter but i may be wrong
It is generally not a good idea to extend host objects like this. You risk tripping over a future implementation of Array.random by the client that behaves differently than yours, breaking future code. You could at least check to make sure it doesn't exist before adding it.
1
const ArrayRandomModule = {
  // get random item from array
  random: function (array) {
    return array[Math.random() * array.length | 0];
  },

  // [mutate]: extract from given array a random item
  pick: function (array, i) {
    return array.splice(i >= 0 ? i : Math.random() * array.length | 0, 1)[0];
  },

  // [mutate]: shuffle the given array
  shuffle: function (array) {
    for (var i = array.length; i > 0; --i)
      array.push(array.splice(Math.random() * i | 0, 1)[0]);
    return array;
  }
}

2 Comments

random misses Math.floor
That what | 0 do

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.