Pick random property from a Javascript object
Suppose you have a Javascript object like {'cat':'meow','dog':'woof' ...} Is there a more concise way to pick a random property from the object than this long winded way I came up with:
function pickRandomProperty(obj) {
var prop, len = 0, randomPos, pos = 0;
for (prop in obj) {
if (obj.hasOwnProperty(prop)) {
len += 1;
}
}
randomPos = Math.floor(Math.random() * len);
for (prop in obj) {
if (obj.hasOwnProperty(prop)) {
if (pos === randomPos) {
return prop;
}
pos += 1;
}
}
}
The chosen answer will work well. However, this answer will run faster:
var randomProperty = function (obj) {
var keys = Object.keys(obj);
return obj[keys[ keys.length * Math.random() << 0]];
};
Picking a random element from a stream
function pickRandomProperty(obj) {
var result;
var count = 0;
for (var prop in obj)
if (Math.random() < 1/++count)
result = prop;
return result;
}
I didn't think any of the examples were confusing enough, so here's a really hard to read example doing the same thing.
Edit: You probably shouldn't do this unless you want your coworkers to hate you.
var animals = {
'cat': 'meow',
'dog': 'woof',
'cow': 'moo',
'sheep': 'baaah',
'bird': 'tweet'
};
// Random Key
console.log(Object.keys(animals)[Math.floor(Math.random()*Object.keys(animals).length)]);
// Random Value
console.log(animals[Object.keys(animals)[Math.floor(Math.random()*Object.keys(animals).length)]]);
Explanation:
// gets an array of keys in the animals object.
Object.keys(animals)
// This is a number between 0 and the length of the number of keys in the animals object
Math.floor(Math.random()*Object.keys(animals).length)
// Thus this will return a random key
// Object.keys(animals)[0], Object.keys(animals)[1], etc
Object.keys(animals)[Math.floor(Math.random()*Object.keys(animals).length)]
// Then of course you can use the random key to get a random value
// animals['cat'], animals['dog'], animals['cow'], etc
animals[Object.keys(animals)[Math.floor(Math.random()*Object.keys(animals).length)]]
Long hand, less confusing:
var animalArray = Object.keys(animals);
var randomNumber = Math.random();
var animalIndex = Math.floor(randomNumber * animalArray.length);
var randomKey = animalArray[animalIndex];
// This will course this will return the value of the randomKey
// instead of a fresh random value
var randomValue = animals[randomKey];
If you are capable of using libraries, you may find that Lo-Dash JS library has lots of very useful methods for such cases. In this case, go ahead and check _.sample()
.
(Note Lo-Dash convention is naming the library object _. Don't forget to check installation in the same page to set it up for your project.)
_.sample([1, 2, 3, 4]);
// → 2
In your case, go ahead and use:
_.sample({
cat: 'meow',
dog: 'woof',
mouse: 'squeak'
});
// → "woof"
You can just build an array of keys while walking through the object.
var keys = [];
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) {
keys.push(prop);
}
}
Then, randomly pick an element from the keys:
return keys[keys.length * Math.random() << 0];