Pick random property from a Javascript object

JavascriptRandom

Javascript Problem Overview


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

Javascript Solutions


Solution 1 - Javascript

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

Solution 2 - Javascript

http://geomblog.blogspot.com/2008/01/happy-birthday-don-knuth.html">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;
}

Solution 3 - Javascript

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

Solution 4 - Javascript

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"

Solution 5 - Javascript

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

Solution 6 - Javascript

If you're using underscore.js you can do:

_.sample(Object.keys(animals));

Extra:

If you need multiple random properties add a number:

_.sample(Object.keys(animals), 3);

If you need a new object with only those random properties:

const props = _.sample(Object.keys(animals), 3);
const newObject = _.pick(animals, (val, key) => props.indexOf(key) > -1);

Solution 7 - Javascript

You can use the following code to pick a random property from a JavaScript object:

function randomobj(obj) {
var objkeys = Object.keys(obj)
return objkeys[Math.floor(Math.random() * objkeys.length)]
}
var example = {foo:"bar",hi:"hello"}
var randomval = example[randomobj(example)] // will return to value
// do something

Solution 8 - Javascript

Another simple way to do this would be defining a function that applies Math.random() function.

This function returns a random integer that ranges from the 'min'
function getRandomArbitrary(min, max) {
  return Math.floor(Math.random() * (max - min) + min);
}
Then, extract either a 'key' or a 'value' or 'both' from your Javascript object each time you supply the above function as a parameter.
var randNum = getRandomArbitrary(0, 7);
var index = randNum;
return Object.key(index); // Returns a random key
return Object.values(index); //Returns the corresponding value.

Solution 9 - Javascript

A lot of great answers here, so let me just try to spread the awareness of the bitwise NOT (~) operator in its double-trouble variant (which I'm pretty sure I learned about on StackOverflow, anways).

Typically, you'd pick a random number from one to ten like this:

Math.floor(Math.random()*10) + 1

But bitwise operation means rounding gets done faster, so the following implementation has the potential to be noticeably more performant, assuming you're doing enough truckloads of these operations:

~~(Math.random()*10) + 1

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBemmuView Question on Stackoverflow
Solution 1 - JavascriptLawrence WhitesideView Answer on Stackoverflow
Solution 2 - JavascriptDavid LeonardView Answer on Stackoverflow
Solution 3 - JavascriptPaul JView Answer on Stackoverflow
Solution 4 - JavascriptSelfishView Answer on Stackoverflow
Solution 5 - JavascriptkennytmView Answer on Stackoverflow
Solution 6 - JavascriptNeluView Answer on Stackoverflow
Solution 7 - JavascriptLol SuperView Answer on Stackoverflow
Solution 8 - JavascriptSushant ChaudharyView Answer on Stackoverflow
Solution 9 - JavascriptDominik BošnjakView Answer on Stackoverflow