user3354777
user3354777

Reputation: 39

Sort JS object by decrementing value (with unknown key)

I'm trying to sort a simple object with unknown keys by highest integer value. Is there neat code to do this?

I've tried this, but with no success.

let fixSort = {};
  Object.keys(leaderboard).sort().forEach(function(key){
  fixSort[key] = leaderboard[key];
});
console.log(fixSort);

Here is the object:

let leaderboard = {
  "Bob" : 2,
  "Jimmy" : 1,
  "Emma" : 6
}

My goal is to have it sorted as:

{
  "Emma" : 6,
  "Bob" : 2,
  "Jimmy" : 1
}

Upvotes: 1

Views: 609

Answers (4)

Brett DeWoody
Brett DeWoody

Reputation: 62781

Another option - use Object.entries to create an array from the leaderboard, sort it by value, then rebuild individual objects into an array, to maintain the sorted order.

const leaderboard = {
  "Bob" : 2,
  "Jimmy" : 1,
  "Emma" : 6
}

console.log(Object.entries(leaderboard).sort((a,b) => b[1] - a[1]).map(person => ({[person[0]]: person[1]})))

Upvotes: 1

Nitin Sharma
Nitin Sharma

Reputation: 419

let leaderboard = {
  "Bob" : 2,
  "Jimmy" : 1,
  "Emma" : 6
}

var newObj={};

Object.keys(leaderboard).sort((a,b)=>leaderboard[b]-leaderboard[a]).forEach((i, v)=> newObj[i]=leaderboard[i]);

enter image description here

For change Object to sorted array, Because If you try to expand the obj in console it will show, you again unsorted, but in real it is sorted, For completely clear, our doubt, we can change this object to array use below code

var result = Object.keys(newObj).map(function(key) {
  return [key, newObj[key]];
});
console.log(result);

it will look like below image enter image description here

Upvotes: 0

charley
charley

Reputation: 198

You're close, but Array.prototype.sort can take a custom compare function. That's what you want.

// Gives you an array
const keyArray = Object.keys(leaderboard)
const fixedSort = keyArray.sort((a, b) => {
  if (leaderboard[a] > leaderboard[b]) {
    return 1
  }
  return -1
})
console.log(fixedSort);

Upvotes: 0

Jonas Wilms
Jonas Wilms

Reputation: 138307

Well "you could":

 const fixSort = {};

 for(const [k, v] of Object.entries(leaderboard).sort((a, b) => a[1] - b[1]))
  fixSort[k] = v;
 }

But thats honestly a bad way to structure this (as adding new key-value pairs is impossible as you have to recreate the whole thing). Instead use an array of objects:

  const leaderboard = [
   { name: "Jack", score: 7 },
   //...
 ];

If you need a lookuptable, then just create one based on that object:

 const byName = {};
 for(const player of leaderboard)
   byName[player.name] = player;

For sure you can also sort the array:

 leaderboard.sort((a, b) => a.score - b.score);

Then you can easily add / remove players.

 function addToLeaderBoard(player) {
   leaderboard.push(player);
   leaderboard.sort((a, b) => a.score - b.score);
   byName[player.name] = player;
 }

Upvotes: 4

Related Questions