Until ES2015, JavaScript object properties had no defined order. They do now, but that order isn't respected by for-in
or Object.keys
, only by new features like Object.getOwnPropertyNames
. It's also more complicated than it seems and of very limited use.
There's almost never any good reason to try to put an object in a specific order. If you want order, use an array, or in ES2015 use a Map
(see below).
But that said, in ES2015, with property names like yours, it's possible: The only way to set the order of the properties in an object is to determine the order in which they're created, which (for properties that aren't array indexes) is the order they'll be in. So you can do this by getting all the property names, determining the order you want them in, and then creating a new object, adding the properties in that order.
Beware, though, that certain classes of property names (what we call "array indexes") are sorted differently. None of your property names meets the definition, but (say) "123"
would.
Here's an example of doing it, if you really want to (I've happily used ES2015's arrow functions, since this only works in ES2015):
// The object
let obj = {
"William_Hill":{},
"bet365":{},
"royal panda":{"pay":0},
"karamba":{"roller":0,"braned":0,"pay":0},
"betfred":{"braned":0}
};
// Get its names, sort them by how may sub-props there are
let names = Object.keys(obj);
names.sort((a, b) => Object.keys(obj[a]).length - Object.keys(obj[b]).length);
// Get the new object
let newObj = names.reduce((acc, name) => {
acc[name] = obj[name];
return acc;
}, {});
// Show its property names
console.log(Object.getOwnPropertyNames(newObj));
Naturally, that can be shorter, I've kept the steps separate for clarity. Similarly, I go back and forth on that use of reduce
, you could do the last bit like this instead:
// Get the new object
var newObj = {};
names.forEach(name => {
acc[name] = obj[name];
});
Here's an example using a Map
instead, which offers much less complicated ordering of entries (no worries about "array indexes"):
// The object
let obj = {
"William_Hill":{},
"bet365":{},
"royal panda":{"pay":0},
"karamba":{"roller":0,"braned":0,"pay":0},
"betfred":{"braned":0}
};
// Get its names, sort them by how may sub-props there are
let names = Object.keys(obj);
names.sort((a, b) => Object.keys(obj[a]).length - Object.keys(obj[b]).length);
// Get the map
let map = new Map();
names.forEach(name => {
map.set(name, obj[name]);
});
// Show its property names
console.log(Array.from(map.keys()));