1

I am trying to render a high score ordered list using an JavaScript object that looks something like this:

{user1: 5, user2: 10}

Using the following code I can generate each list item individual:

Object.entries(data).forEach(([key, value]) => {
    const li = document.createElement('li');
    li.innerHTML = `${key}: ${value}`;
    scoreList.append(li);
});

Now I am looking for a way to sort each list item based on the object value. I know we have the sort function that works on arrays and using the following code almost works:

const keysSorted = Object.entries(data).sort((a, b) => {
    return data[a] - data[b];
});

However it does not keep the object values, it just returns a sorted array with each key. My wanted result looks like this:

<ol>
    <li>user2: 10</li>
    <li>user1: 5</li>
</ol>
Vera Perrone
  • 369
  • 1
  • 15

1 Answers1

2

Despite the small flaw in .sort, you can just reduce it back to it's previous form. Just map the key/value back to an object:

const data = { user1: 5, user2: 10 };
const keysSorted = Object.entries(data)
  .sort((a, b) => b[1] - a[1])
  .reduce((a, b) => Object.assign(a, { [b[0]]: b[1] }), {});
console.log(keysSorted);

Notes:

Armin Šupuk
  • 809
  • 1
  • 9
  • 19
  • should this be ok:`Object.entries(data) .sort((a, b) => b[1] - a[1]) .forEach((user) => { const li = document.createElement('li'); li.innerHTML = `${user[0]}: ${user[1]}`; scoreList.append(li); });` – Vera Perrone Apr 10 '18 at 17:43
  • 1
    Of course, it's perfectly fine, I personally prefer to separate data manipulation (as sorting) from rendering, but it looks good to me – Armin Šupuk Apr 10 '18 at 17:46