How to combine countBy and filter in lodash

I have following data array:

const data = [
  { year: 1900, title: 'test 1' },
  { year: 2000, title: 'test 2' },
  { year: 2000, title: 'test 3' },
  { year: 2000, title: 'test 4' },
];

My aim is to get an array of years where each given year appear more than twice:

[2000]

the countBy is fairly easy to achieve by:

_.chain(data)
.countBy('year')
.value()

which returns the following object:

{'1900': 1, '2000': 3}

I’m stumbling upon the filtering part. I tried the following but it returns me an empty array:

_.chain(data)
  .countBy('year')
  .filter((o) => {
    o > 2;
  })
  .value();

What would be the correct way?

26 thoughts on “How to combine countBy and filter in lodash”

  1. You only have a small typo in your code:

    filter((o) => {
        o > 2;
      })
    

    should be

    filter((o) => {
        return o > 2;
      })
    

    or

    filter((o) => o > 2)
    

    Otherwise, you will always return undefined, therefore everything is filtered out.

    Reply
  2. const data = [
      { year: 1900, title: 'test 1' },
      { year: 2000, title: 'test 2' },
      { year: 2000, title: 'test 3' },
      { year: 2000, title: 'test 4' },
    ];
    
    const yearTitlesMap = _.groupBy(data, 'year');
    const yearsAppearingMoreThanTwice = _.filter(_.keys(yearTitlesMap), year => yearTitlesMap[year].length>2);
    
    console.log(yearsAppearingMoreThanTwice);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js" integrity="sha512-90vH1Z83AJY9DmlWa8WkjkV79yfS2n2Oxhsi2dZbIv0nC4E6m5AbH8Nh156kkM7JePmqD6tcZsfad1ueoaovww==" crossorigin="anonymous"></script>
    Reply
  3. Replace _.filter() with _.pick() because filter would return only the values ([3]), and not keys (the years). You should also return from the callback – o => o > 2.
    Afterwards, get the an array of the keys (the years), and map them to numbers (if needed).

    const data = [{"year":1900,"title":"test 1"},{"year":2000,"title":"test 2"},{"year":2000,"title":"test 3"},{"year":2000,"title":"test 4"}];
    
    const result = _(data)
      .countBy('year')
      .pickBy(o => o > 2)
      .keys()
      .map(Number) // <- if you want the years as numbers
      .value();
      
    console.log(result);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js" integrity="sha512-90vH1Z83AJY9DmlWa8WkjkV79yfS2n2Oxhsi2dZbIv0nC4E6m5AbH8Nh156kkM7JePmqD6tcZsfad1ueoaovww==" crossorigin="anonymous"></script>
    Reply

Leave a Comment