Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find the person with most blog likes in an array of objects

I have an array of blog objects, how can I find the author with highest number of likes in total?

I have tried using a for loop and pushing each object with a different author into a separate array, then calculating the total number of likes in the array. I'm having difficulties comparing the objects with each other and keep getting several arrays for the same author.

const blogs = [
  {
    title: 'First',
    author: 'Jane',
    likes: 4,
  },
  {
    title: 'Second',
    author: 'Joe',
    likes: 1,
  },
  {
    title: 'Third',
    author: 'Jane',
    likes: 7,
  },
  {
    title: 'Fourth',
    author: 'Jack',
    likes: 1,
  },
  {
    title: 'Fifth',
    author: 'Joe',
    likes: 5,
  }
]

The number of authors is not limited and in this example, the result should be something like:

{
    author: 'Jane',
    likes: 11,
  }
like image 656
lauraleonilla Avatar asked Jul 11 '19 18:07

lauraleonilla


2 Answers

You can use reduce, map each author on object and add it's like

const blogs = [ { title: 'First', author: 'Jane', likes: 4, }, { title: 'Second', author: 'Joe', likes: 1, }, { title: 'Third', author: 'Jane', likes: 7, }, { title: 'Fourth', author: 'Jack', likes: 1, }, { title: 'Fourth', author: 'Joe', likes: 5, } ]

let authorLikes = blogs.reduce((op, {author, likes}) => {
  op[author] = op[author] || 0
  op[author] += likes
  return op
},{})

console.log(authorLikes)

You can extend it further to get most likes

// to find most likes
let mostLikes = Object.keys(authorLikes).sort((a,b)=> authorLikes[b] - authorLikes[a])[0]

console.log(mostLikes, authorLikes[mostLikes])
like image 134
Code Maniac Avatar answered Sep 27 '22 18:09

Code Maniac


If you were solely looking for the author with the most likes, you could do this in one pass with .reduce().

The method below keeps track of the authors' total likes (sums), and the individual author with the most (most), to simultaneously sum and compare.

const blogs = [ { title: 'First', author: 'Jane', likes: 4, }, { title: 'Second', author: 'Joe', likes: 1, }, { title: 'Third', author: 'Jane', likes: 7, }, { title: 'Fourth', author: 'Jack', likes: 1, }, { title: 'Fourth', author: 'Joe', likes: 5, } ];

const getMostLikes = (blogs) => blogs
  .reduce(({sums,most}, {likes, author}) => {
    sums[author] = likes = (sums[author] || 0) + likes;
    if (likes > most.likes) most = {author,likes};
    return {sums,most};
  }, {sums: {}, most: {likes:0} })
  .most;

console.log( getMostLikes(blogs) );

* Thanks to CodeManiac's answer, I've shortened the instantiation/addition using out.sums[author] || 0 instead.

like image 22
Santi Avatar answered Sep 27 '22 18:09

Santi