2

This is probably a classic issue: I have a "dictionary" of scores for each player:

var scores = {
    'player1' : 9,
    'player2' : 3,
    'player3' : 7,
    'player4' : 5
}

I want to transform this into a Leaderboard with as key, the position calculated on the number of players and the value, the name of the player:

var leaderboard = {
    1 : 'player1',
    2 : 'player3',
    3 : 'player4',
    4 : 'player2'
}

How do I do this in a clean way, without messing too much with temporary lists and dictionaries? Thank you.

Nick Parsons
  • 45,728
  • 6
  • 46
  • 64
Fabio Magarelli
  • 1,031
  • 4
  • 14
  • 47
  • PS. I read this: https://stackoverflow.com/questions/23013573/swap-key-with-value-json my issue is different cause the scores for each players can be the same and also I have to transform the keys so that it matches the number of partecipants – Fabio Magarelli Mar 19 '20 at 13:29

1 Answers1

2

You could grab the entries of your object (with Object.entries()) and .sort() them to get the order for your leaderboard. Then use .map() on your sorted entries to map them to objects, where the object's value is the player, and the index+1 (i+1) of the entry is the key. You can then use Object.assign() to build a larger object from this array:

const scores = {
    'player1' : 9,
    'player2' : 3,
    'player3' : 7,
    'player4' : 5
};

const leaderboard = Object.assign(
   {}, 
   ...Object.entries(scores)
       .sort(([,a], [,b]) => b-a)
       .map(([p], i) => ({[i+1]: p}))
);
console.log(leaderboard);

Note: Your required output is an object with numbered continuous keys. Normally, you would use an array to store this type of data, where the item at position 0 is the "top" leader. For an array output, you simplify the above code to be:

const scores = {
    'player1' : 9,
    'player2' : 3,
    'player3' : 7,
    'player4' : 5
};

const leaderboard = Object.entries(scores)
       .sort(([,a], [,b]) => b-a)
       .map(([p]) => p)

console.log(leaderboard);
Nick Parsons
  • 45,728
  • 6
  • 46
  • 64