Question

I have this object:

{ foo: 1, bar: 2, cheese: 3 }

I want to shuffle the elements, so it becomes:

{ bar: 2, cheese: 3, foo: 1 }

Or some other kind of combination. Is there a function to do this? This is because I want to produce varying results when using JSON.stringify on it. The only answers I could find on the internet refer to shuffling objects within an array.

Thanks.

Was it helpful?

Solution

JS object properties have no intrinsic order. Most JS runtimes preserve the ordering that the keys were added in, but that is not a language requirement and you should not rely on it. For example, it would be perfectly valid for JSON.stringify to just always serialize keys in alphabetical order or randomize them.

If the ordering is important, you could potentially keep a set of two arrays to track the keys and values.

OTHER TIPS

Object properties (as of 2014) do NOT have a defined order and there is no language support for defining or changing the order of the properties. Per the language specification, order does not have to be preserved in any way.

If you want a defined order, you should use an Array.

To randomize the order of properties in an object you can access the keys, shuffle them, then assemble a new object. Here's a function:

let obj = { "a":1, "b":2, "c":3, "d":4 }

function shuffleObject(obj){
    // new obj to return
  let newObj = {};
    // create keys array
  var keys = Object.keys(obj);
    // randomize keys array
    keys.sort(function(a,b){return Math.random()- 0.5;});
  // save in new array
    keys.forEach(function(k) {
        newObj[k] = obj[k];
});
  return newObj;
}

console.log(shuffleObject(obj));
console.log(shuffleObject(obj));
console.log(shuffleObject(obj));

You could create a Shuffle custom function ?

function shuffle(o){ //v1.0
    for(var j, x, i = o.length; i; j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
    return o;
};

then use it like shuffle(myArray)

You need to transform your object into an Array...

Properties have no order, but this trick worked for me (lodash required) :

function shuffle(array) {
  var currentIndex = array.length, temporaryValue, randomIndex;

  // While there remain elements to shuffle...
  while (0 !== currentIndex) {

    // Pick a remaining element...
    randomIndex = Math.floor(Math.random() * currentIndex);
    currentIndex -= 1;

    // And swap it with the current element.
    temporaryValue = array[currentIndex];
    array[currentIndex] = array[randomIndex];
    array[randomIndex] = temporaryValue;
  }
  return array;
}

function shuffleObject(obj) {
  // Get object key into tmp array in random order
  var keys = this.shuffle(_.keys(obj));

  // instantiate new object who will be returned
  var newObj = {};

  // Iterate over keys to populate object with same properties in a different order
  keys.forEach(function(elm, index){
    newObj[elm] = obj[elm];
    if(index === keys.length-1){
      return newObj;
    }
  })
}
console.log(shuffleObject({ "A": 1, "B": 2, "C": 3, "D": 4 });
//{ "B": 2, "C": 3, "D": 4,"A": 1 }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top