Search code examples
javascriptlodash

How to create an object with the name and frequency count from an object array with lodash


I have an array like this:

const blogs = [
  {
    _id: "5a422a851b54a676234d17f7",
    title: "React patterns",
    author: "Michael Chan",
    url: "https://reactpatterns.com/",
    likes: 7,
    __v: 0
  },
  {
    _id: "5a422ba71b54a676234d17fb",
    title: "TDD harms architecture",
    author: "Robert C. Martin",
    url: "http://blog.cleancoder.com/uncle-bob/2017/03/03/TDD-Harms-Architecture.html",
    likes: 0,
    __v: 0
  },
  {
    _id: "5a422bc61b54a676234d17fc",
    title: "Type wars",
    author: "Robert C. Martin",
    url: "http://blog.cleancoder.com/uncle-bob/2016/05/01/TypeWars.html",
    likes: 2,
    __v: 0
  }  
]

I want to have at least an object like this:

{
    "name":"Robert C. Martin",
    "blogs": 2,
}

I try with lodash but can't understand how I can count the number of blogs for one author.

_.maxBy(blogs, 'author') //gives me the author with the maximum of blogs
_.groupBy(blogs, 'author') // group all blogs in an array under the author name
// _.countBy(blogs,'entries') //that doesn't work

Solution

  • This is easy enough to do with plain JavaScript (see Array.prototype.reduce) if you didnt want to use lodash, for example:

    const blogs = [{
        _id: "5a422a851b54a676234d17f7",
        title: "React patterns",
        author: "Michael Chan",
        url: "https://reactpatterns.com/",
        likes: 7,
        __v: 0
      },
      {
        _id: "5a422ba71b54a676234d17fb",
        title: "TDD harms architecture",
        author: "Robert C. Martin",
        url: "http://blog.cleancoder.com/uncle-bob/2017/03/03/TDD-Harms-Architecture.html",
        likes: 0,
        __v: 0
      },
      {
        _id: "5a422bc61b54a676234d17fc",
        title: "Type wars",
        author: "Robert C. Martin",
        url: "http://blog.cleancoder.com/uncle-bob/2016/05/01/TypeWars.html",
        likes: 2,
        __v: 0
      }
    ];
    
    const blogAuthorCounter = blogs.reduce((obj, blog) => {
      obj[blog.author] = obj[blog.author] ? obj[blog.author] + 1 : 1;
    
      return obj;
    }, {});
    
    Object.entries(blogAuthorCounter).forEach(entry => {
      const [author, count] = entry;
    
      console.log(`${author} = ${count}`);
    });