Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Count and sort by number of occurrences

I have an array like this:

var items = [
  {name: 'popcorn', category: 'snacks'},
  {name: 'nachos', category: 'snacks'},
  ...
  {name: 'coke', category: 'drinks'}
];

I want to get a list of categories ordered by the number of items on it (most items first):

['snacks', 'drinks']

Here is how I did it:

var categories = _.chain(items)
  .countBy(function (i) { return i.category })
  .pairs()
  .sortBy(function (c) { return -c[1] })
  .map(function (c) { return c[0] })
  .value();

So the result of countBy is an object, and I have to use pairs to convert it into an array of arrays in order to sort it.

I wonder if there is a more straightforward way to do it? Built-in function?

like image 735
Endy Tjahjono Avatar asked Sep 29 '13 02:09

Endy Tjahjono


People also ask

How do I count the number of occurrences in a file?

Using grep -c alone will count the number of lines that contain the matching word instead of the number of total matches. The -o option is what tells grep to output each match in a unique line and then wc -l tells wc to count the number of lines. This is how the total number of matching words is deduced.

How do you count grep results?

Counting Matches With grepThe grep command has the -c flag, which will count the number of lines matched and print out a number. This is useful for lots of things, such as searching through log files for the number of entries from a particle IP, endpoint, or other identifier.

How do I count duplicate lines in Linux?

The uniq command has a convenient -c option to count the number of occurrences in the input file. This is precisely what we're looking for. However, one thing we must keep in mind is that the uniq command with the -c option works only when duplicated lines are adjacent.


2 Answers

I wonder if there is a built-in function?

Nope, your approach is fine.

more straightforward way to do it?

You could shorten it a bit by passing only property names, not functions:

var categories = _.chain(items)
  .countBy("category")
  .pairs()
  .sortBy(1).reverse()
  .pluck(0)
  .value();
like image 66
Bergi Avatar answered Nov 17 '22 07:11

Bergi


I think this is pretty good. You could cram it into a one-step reduce but that would wind up being more complicated than what your code looks like now. If you're going to be reusing this a bunch, you could use compose and partial to reduce the overall amount of code you're writing. Also, check out lodash as an alternative to underscore - it's got more juice.

like image 30
JSager Avatar answered Nov 17 '22 06:11

JSager