-2

I'm trying to make a simple "top 3" of the users that have the most messages. So far I was able to group the user and messages inside an array of objects

let data = [ { message: 'fsaasfafs', user: 'John' },
  { message: 'asgsgaasgags', user: 'John' },
  { message: 'asgsgaasgags', user: 'John' },
  { message: 'asgsgaasgags', user: 'Smith' },
  { message: 'asgsgaasgags', user: 'Samantha' },
  { message: 'asgsgaasgags', user: 'Luis' },
  { message: 'asgsgaasgags', user: 'Samantha' }]

console.log(data);

In this case, the top 3 would be John - 3 ; Samantha - 2; Smith or Luis (does not matter) - 1 I would like a map with the user as key and the amount of messages.

Any help please?

4
  • Please post what you have tried to achieve the desired result. Commented Nov 7, 2019 at 11:01
  • @jonas - How does sorting answer this question? (I've added a dupe that I think does, I'm just curious about the one you picked.) Commented Nov 7, 2019 at 11:02
  • @t.j. well, I was just about to do the same (adding a few more duplicates), but you two were faster :) Commented Nov 7, 2019 at 11:03
  • let statsMap = {}; data.forEach(message => { if(statsMap.hasProperty(message.user)) { } else { statsMap[message.user] = } }); i got stuck Commented Nov 7, 2019 at 11:05

2 Answers 2

1

    let data = [ { message: 'fsaasfafs', user: 'John' },
      { message: 'asgsgaasgags', user: 'John' },
      { message: 'asgsgaasgags', user: 'John' },
      { message: 'asgsgaasgags', user: 'Smith' },
      { message: 'asgsgaasgags', user: 'Samantha' },
      { message: 'asgsgaasgags', user: 'Luis' },
      { message: 'asgsgaasgags', user: 'Samantha' }];
      
    let topM = Object.entries(data.reduce((acc, c) => { acc[c.user] = (acc[c.user] || 0 ) + 1; return acc;},{})).sort(function (a, b) { return b[1] - a[1];}).slice(0, 3);
    console.log(topM);

Hope This helps you !

Sign up to request clarification or add additional context in comments.

Comments

0

You could do like get count of each user message

  1. Then you could count the each user messages using Array#reduce with Array#filter(this will match the user count in array for each user)

let data = [ { message: 'fsaasfafs', user: 'John' },
  { message: 'asgsgaasgags', user: 'John' },
  { message: 'asgsgaasgags', user: 'John' },
  { message: 'asgsgaasgags', user: 'Smith' },
  { message: 'asgsgaasgags', user: 'Samantha' },
  { message: 'asgsgaasgags', user: 'Luis' },
  { message: 'asgsgaasgags', user: 'Samantha' }]
  
 let user_list = data.reduce((a,b,c,d)=>{
   if(Object.keys(a).indexOf(b.user) == -1){
    a[b.user] = d.filter(i=>i.user == b.user).length
   }
   return a
 },{})
 
 console.log(user_list)

3 Comments

please explain :/
This is not very efficient. Not only does it involve three iterations (map, filter, and reduce) when it could be done in one, it also has a nested iteration happening with indexOf, which gives it a O(n²) time complexity. On top of that, this question has been asked before and has useful answers already.
@trincot i just update method with single parent loop

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.