3

Given a dictionary-like object in Javascript such as {a:1, b:-2, c:42}, is there a simple way to randomly choose a property?

In the above example, I would like to have a function that would return a, b or c randomly.

The solution I've come up with is like the following:

    var proplist = []
    forEach(property in foo) {
        if(propertyIsEnumerable(foo[property]) {
            proplist.push(property);
        }
    }
    var n = proplist.length;
    // randomly choose property (randInt(n) returns a random integer in [0,n))
    proplist[randInt(n)];

Is there a more idiomatic way to do this?

tlehman
  • 5,125
  • 2
  • 33
  • 51
  • possible duplicate of [Pick random property from a Javascript object](http://stackoverflow.com/questions/2532218/pick-random-property-from-a-javascript-object) – Gazler Jan 24 '12 at 22:58

3 Answers3

7

Use Object.keys (or even Object.getOwnPropertyNames) to get a list of all properties. Then, select a random property by multiplying Math.random() with the length of the list, floored.

var propList = {}; //...
var tmpList = Object.keys(propList);
var randomPropertyName = tmpList[ Math.floor(Math.random()*tmpList.length) ];
var propertyValue = propList[randomPropertyName];
Rob W
  • 341,306
  • 83
  • 791
  • 678
5

This can be quite idiomatic with underscore.js:

 randomProp = _.shuffle(_.keys(obj))[0]

Edit: actually, one should use _.sample for that.

georg
  • 211,518
  • 52
  • 313
  • 390
  • Of course this will involve shuffling the entire list of keys, with probably `n - 1` calls to `random`, where `n` is the length of `keys`. As shown in another answer and the question, this is doable with only a single `random` call. – Scott Sauyet Apr 10 '16 at 01:18
  • @ScottSauyet: of course, this is a wrong answer, edited. – georg Apr 10 '16 at 09:27
  • @georg your link for `_.sample` points to lodash, not underscore, although the function is available in both – krodmannix May 02 '16 at 14:28
2

Or if you want to write a reusable function for this, you could do

const randomFrom = list => list[Math.floor(list.length * Math.random())];
const randomProp = obj => randomFrom(Object.keys(obj));

randomProp(propList); //=> one of the keys of propList

This will return undefined if your object has no properties, but that's probably the best we could do in any case.

Scott Sauyet
  • 49,207
  • 4
  • 49
  • 103