Irakli Tchigladze
Irakli Tchigladze

Reputation: 723

Sorting an object based on property integer values in descending order

So, i have object of cities with scores attached to them, like so :
let cityScores = { Milan: 1, Malta: 3, Palma: 5, Ibiza: 2, Porto: 1 };
What i want to do is to get an array, with the highest-scoring city as its first item (in this case, Palma), and following cities by descending scores.

I thought long and hard about this, and came up with this solution. I just wanted to ask, isn't there anything better out there? A useful method or some other way out that i might be missing? This is how i do it :

First of all, i find max value in the object. Then, i check for every city and i make sure that the one with highest value is/are in the beginning of array. Then i tried using .push() to push the lowest-scoring cities to the end, but i just couldn't. I can't push "city" properly while i'm still looping over these cities, because cities are randomly. The best approach i found was to "remember" cities by their score and store them in these arrays (secondaryCities, tertiaryCities, etc) and then push them one by one.

let cityScores = { Milan: 1, Malta: 3, Palma: 5, Ibiza: 2, Porto: 1 };
let cityScoreKeys = Object.keys(cityScores);
let cityScoreValues = Object.values(cityScores);
let maxScore = Math.max(...cityScoreValues);
let arrangedCities = [];
let secondaryCities = [];
let tertiaryCities = [];
let quaternaryCities = [];
for (i = 0; i < cityScoreKeys.length; i++) {
  if (cityScores[cityScoreKeys[i]] == maxScore) {
    arrangedCities.unshift(cityScoreKeys[i]);
  } else if (cityScores[cityScoreKeys[i]] === maxScore - 1) {
    secondaryCities.push(cityScoreKeys[i]);
  } else if (cityScores[cityScoreKeys[i]] === maxScore - 2) {
    tertiaryCities.push(cityScoreKeys[i]);
  } else if (cityScores[cityScoreKeys[i]] === maxScore - 3) {
    quaternaryCities.push(cityScoreKeys[i]);
  }
}
let nonMaxCities = [secondaryCities, tertiaryCities, quaternaryCities];
for (i = 0; i < nonMaxCities.length; i++) {
  arrangedCities.push(...nonMaxCities[i]);
}

Upvotes: 1

Views: 104

Answers (5)

nash11
nash11

Reputation: 8680

You can simply use Object.keys and sort the keys based on the value in a single line.

Here is a working example.

let cityScores = {
  Milan: 1,
  Malta: 3,
  Palma: 5,
  Ibiza: 2,
  Porto: 1
};

const sortedCities = Object.keys(cityScores).sort((a, b) => cityScores[b] - cityScores[a]);

console.log(sortedCities);

Upvotes: 2

Biplab Malakar
Biplab Malakar

Reputation: 788

You can use my solution, I just take the help of inbuilt JavaScript functions. Steps are

  1. Convert object into 2D array(like [["Milan", 1], ["Malta", 3]])
  2. Then sort the array by the score of each item (index 1).
  3. Return only city name(index 0)

let obj = { Milan: 1, Malta: 3, Palma: 5, Ibiza: 2, Porto: 1 };
let newArr = Array.from(Object.entries(obj)).sort((a,b)=> b[1]-a[1]).map(d=> d[0]);
console.log(newArr);

Upvotes: 1

pwilcox
pwilcox

Reputation: 5763

Convert to array using Object.entries and then use methods available to an array:

let parsed = 
    Object.entries(cityScores)
    .sort((a, b) => b[1] - a[1])
    .map(x => x[0]);

Thanks JasonWoof for the simpler sort function.

Upvotes: 2

Renan Barbosa
Renan Barbosa

Reputation: 1084

Add them to an array so you can sort them as you need

let cityScores = { Milan: 1, Malta: 3, Palma: 5, Ibiza: 2, Porto: 1 };

let sortable = [];
for (var score in cityScores) {
    sortable.push([score, cityScores[score]]);
}

sortable.sort(function(a, b) {
    return a[1] - b[1];
});

Upvotes: 1

Łukasz Nojek
Łukasz Nojek

Reputation: 1641

Here's my solution:

let cityScores = { Milan: 1, Malta: 3, Palma: 5, Ibiza: 2, Porto: 1 };

let obj = Object.keys(cityScores).map(function(key) {
  return {key, value: cityScores[key]};
});

let result = obj.sort((a,b) => b.value - a.value);

console.log(result);

Upvotes: 3

Related Questions