Reputation: 197
As you may assume - I'm stuck ;) My problem is that I have an object with some other objects within:
let players = {
buggy: {
name: 'John',
surname: 'Cocroach',
rank: 872
},
valentino: {
name: 'Antonio',
surname: 'Valencia',
rank: 788
},
tommy: {
name: 'Tom',
surname: 'Witcher',
rank: 101
},
};
And what I want to do is to sort "players" object by "rank": (tommy(101), valentino(788), buggy(872)) or by a string (e.g. "surname"). What is more I want it to still be an object (I am using it in several other functions ;) )
I tried some ideas form here (e.g. converting to an array), but all were uneffective. What would be the best option?
Upvotes: 1
Views: 64
Reputation: 33726
You can sort the keys and then return an iterable object. This way you will be able to loop it.
Another approach is using a simple array with the keys, Etc, however this approach (iterable object) is cleaner.
Let's create a function called sortAsIterable(..)
, this function will return an iterable object of players.
Important: Be careful with IE
let players = { buggy: { name: 'John', surname: 'Cocroach', rank: 872 }, valentino: { name: 'Antonio', surname: 'Valencia', rank: 788 }, tommy: { name: 'Tom', surname: 'Witcher', rank: 101 },};
function sortAsIterable(obj) {
let sortedKeys = Object.keys(obj).sort(function(a, b) {
return obj[a].rank - obj[b].rank;
});
let myIterable = {}, index = 0;
myIterable[Symbol.iterator] = function*() {
for (let k of sortedKeys) yield {[k]: obj[k]};
};
return myIterable;
}
// Object sorted.
let sortedPlayers = sortAsIterable(players);
players.buggy.name = "Ele"; // This is to illustrate the live access to the values.
// Now you can iterate them .
// You can do this as much as you want, for example in different parts of your code.
for (let player of sortedPlayers) console.log(player);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 1
Reputation: 138527
As objects are stored by reference you can have an array and an object operating on the same underlying player objects:
const playersByRank = Object.values(players).sort((a, b) => a.rank - b.rank);
Now you can access a player either via its name under players
or via its relative rank under playersByRank
, e.g. taking the player "buggy" is the same as taking the highest ranked player:
players.buggy.test = "works";
console.log(playersByRank[0].test);
Upvotes: 1