0

Hello everyone,

what I'd like to achieve is to shuffle all the object's properties including their values...

object:

    var numbers = { one : 1, two : 2, three : 3};

result:

     Object {two: 2, one: 1, three: 3} 

or any other variation

I have tried couple of array shuffle methods but none of them worked for me...

Wracker
  • 589
  • 10
  • 32
  • Shuffle object properties? For which purpose? I mean: if it's for visualization then shuffle output, not properties...it doesn't matter where they are (and in JS **order also is unspecified**). – Adriano Repetti Oct 22 '14 at 08:52
  • Two question: 1) What have you tried? 2) Why are you trying to do this? – Aadit M Shah Oct 22 '14 at 08:52
  • possible duplicate of [Sorting JavaScript Object by property value](http://stackoverflow.com/questions/1069666/sorting-javascript-object-by-property-value) – JJJ Oct 22 '14 at 08:53
  • I just wanted to know if there is such a possibility. – Wracker Oct 22 '14 at 09:00

2 Answers2

5

As of ECMAScript 2015 (ES2015, aka ES6), object properties do have an order (they didn't before):

  1. Let keys be a new empty List.
  2. For each own property key P of O that is an integer index, in ascending numeric index order
    • Add P as the last element of keys.
  3. For each own property key P of O that is a String but is not an integer index, in property creation order
    • Add P as the last element of keys.
  4. For each own property key P of O that is a Symbol, in property creation order
    • Add P as the last element of keys.
  5. Return keys.

Consequently, it's now possible to do what you asked, by creating a new object and adding the properties to it in the order you want them to appear:

let numbers = { one : 1, two : 2, three : 3};
numbers = Object.keys(numbers)
    .map((key) => ({key, value: numbers[key]}))
    .sort((a, b) => b.key.localeCompare(a.key))
    .reduce((acc, e) => {
      acc[e.key] = e.value;
      return acc;
    }, {});
console.log(JSON.stringify(numbers));

Live Example

That's sorted, not shuffled, but instead of sort you can shuffle in any of several ways, as outlined in this question's answers.

That works on ES2015+ JavaScript engines. I'm not saying it (using property order this way) a worthwhile thing to do. :-)

You could argue that that's a bit of an abusage of reduce, but it let me keep it all to one big expression. (Which you could further argue is a silly thing for me to do. :-) )

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
3

Objects are unordered. Some browsers may sort their keys alphabetically, but this is outside of any specification as the spec says unordered.

But what you can do is this:

var keys = Object.keys(numbers);
// drop your preffered shuffle algorithm here
keys.sort(function(a,b) {return Math.random() - 0.5;});
// now you have random keys!

keys.forEach(function(k) {console.log(numbers[k]);});
Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592
  • 1
    Most engines don't sort alphabetically. Nearly all use the order in which the properties were added to the object. This is undocumented (and not quite universal), though. As you say, by specification they have no order. Relying on the order would be a bad idea. :-) – T.J. Crowder Oct 22 '14 at 08:53
  • Oops - so used to PHP's `rand` and MySQL's `RAND` that I keep forgetting JS's `Math.random` is spelled out XD – Niet the Dark Absol Oct 22 '14 at 08:56
  • The ordering [has been specified now](http://www.ecma-international.org/ecma-262/6.0/index.html#sec-ordinary-object-internal-methods-and-internal-slots-ownpropertykeys). – T.J. Crowder Aug 06 '15 at 18:09