1

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]);
}
0

5 Answers 5

3

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);

Sign up to request clarification or add additional context in comments.

Comments

2

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.

1 Comment

simpler sort function: .sort((a, b) => b[1] - a[1])
2

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);

Comments

1

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];
});

Comments

1

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);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.