RDowns
RDowns

Reputation: 659

How to sort a VueJS object in descending order of the number of occurrences?

I have a dynamic object that consists of the number of occurrences from a user selection. The object looks like this:

{ "Excitement": 2, "Competence": 3, "Sophistication": 1 }

This is the function:

rankFactors() {
      const headers = this.headers;
      var counts = {};
      for (var i = 0; i < headers.length; i++) {
        var num = headers[i];
        counts[num] = counts[num] ? counts[num] + 1 : 1;
      }
      return counts;
 }

How do I sort this object so that it is always in descending order? That way I can print it as a 'Top 3' list.

This is my CodeSandbox: https://codesandbox.io/embed/vue-template-mzi03

To reproduce just make selection of personality traits, with multiple options from a few headers.

Upvotes: 0

Views: 1234

Answers (1)

skirtle
skirtle

Reputation: 29092

I think I'd do it something like this:

rankFactors() {
  const headers = this.headers;
  const counts = {};

  for (const header of headers) {
    counts[header] = (counts[header] || 0) + 1;
  }

  const factors = Object.keys(counts).map(header => {
    return {
      name: header,
      count: counts[header]
    }
  });

  factors.sort((a, b) => b.count - a.count);

  return factors;
}

The first stage is very similar to what you had, building up an object of counts. That's an easy data structure to work with for gathering those counts but once that stage is done it's not a great choice for dealing with sorting. For that we're better off with an array.

So next up it converts the object into an array of objects, each of the form {name: 'Excitement', count: 2}. This array is then sorted based on the counts and then returned. You could throw in a .slice(0, 3) if you just want the top 3.

Upvotes: 1

Related Questions