1

I have a array of objects like below:

[  
   {  
      "commentId":1485594783811,
      "topicId":"1485594764668",
      "comments":"hi2",
      "commentDate":"1/31/2017, 12:59:08 PM",
      "userImage":"assets/img/spiritual-icon4.png",
      "username":"k****@gmail.com"
   },
   {  
      "commentId":1485866129370,
      "topicId":"1485853106269",
      "comments":"Hi",
      "commentDate":"1/31/2017, 6:05:29 PM",
      "userImage":"assets/img/spiritual-icon4.png",
      "username":"kv****@gmail.com"
   },
   {  
      "commentId":1485939547285,
      "topicId":"1485853106269",
      "comments":"Hi",
      "commentDate":"2/1/2017, 3:18:34 PM",
      "userImage":"assets/img/spiritual-icon4.png",
      "username":"ki*****9@gmail.com"
   },
   {  
      "commentId":1485947026195,
      "topicId":"1485945483238",
      "comments":"hi",
      "commentDate":"2/1/2017, 4:33:46 PM",
      "userImage":"assets/img/spiritual-icon4.png",
      "username":"ki****9@gmail.com"
   }
]

All the objects contain a topicId and comments(can be empty/null) property. I want to know the count of all the comments based on topicId which is like a primary key.

So I get to know how many users have commented on each topic. I tried some thing like this:

var count = 0;
res.forEach(function(el, i){
    self.data.topicIdArr.push(el.topicId);
});

self.data.topicIdArr.forEach(function(el, i){
    if(res[i].topicId == el){
        self.data.topicIdArr.push(count++);
    }
});

But I don't think its the correct way.

How do I do this?

kittu
  • 6,662
  • 21
  • 91
  • 185
  • First please provide relevant data sample. Second, please share what have you tried. If you have not tried anything, *hint*: `Array.filter` – Rajesh Feb 01 '17 at 12:39
  • 1
    If you are not able to write anything with `Array#filter`, try underscore's countBy method. – marmeladze Feb 01 '17 at 12:40
  • please add the array in literal format. – Nina Scholz Feb 01 '17 at 12:40
  • @Rajesh I heard of array filter but I didn't knew I could apply it in this scenario – kittu Feb 01 '17 at 12:41
  • 1
    @kittu Instead of `.push`, just do `count++` and at the end push it once. – Rajesh Feb 01 '17 at 12:42
  • Need more info. What's the relation between commentID, topicID and comments? How do they link together? In your example, does the comment 'hi2' have the id in commentID? They're both strings, so what happens when multiple comments are made on a topic? DO we have to comapre topicID with the commentID in some way? Or are all these objects comments and do we basically need to count how many times a certain topicID appears in different objects? – Shilly Feb 01 '17 at 12:44
  • If you have a short length of array you can use your way. Else create one time map of objects by Id and use it every time – Vitalii Andrusishyn Feb 01 '17 at 12:44
  • This sounds, like a DB logic rather than a JS one, DB would always be a lot faster too, are you doing this all wrong? – Val Feb 01 '17 at 12:45
  • @Val I didn't want to do this DB side as It has make a ajax call, pass through security and then JPA repository and then count from two tables. I guess javascript is better. What do you say? – kittu Feb 01 '17 at 12:48

3 Answers3

3

You could use an object for counting.

var data = [{ commentId: 1485594783811, topicId: 1485594764668, comments: "hi2", commentDate: "1/31/2017, 12:59:08 PM", userImage: "assets/img/spiritual-icon4.png", username: "k****@gmail.com" }, { commentId: 1485866129370, topicId: 1485853106269, comments: "Hi", commentDate: "1/31/2017, 6:05:29 PM", userImage: "assets/img/spiritual-icon4.png", username: "kv****@gmail.com" }, { commentId: 1485939547285, topicId: 1485853106269, comments: "Hi", commentDate: "2/1/2017, 3:18:34 PM", userImage: "assets/img/spiritual-icon4.png", username: "ki*****9@gmail.com" }, { commentId: 1485947026195, topicId: 1485945483238, comments: "hi", commentDate: "2/1/2017, 4:33:46 PM", userImage: "assets/img/spiritual-icon4.png", username: "ki****9@gmail.com" }],
    count = Object.create(null);

data.forEach(function (a) {
    count[a.topicId] = (count[a.topicId] || 0) + 1;
});

console.log(count);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Then you get the count in the object, like

{
   "1485594764668": 1,
   "1485853106269": 2,
   "1485945483238": 1
}
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • Whats happening inside `count[a.topicId] || 0` You are checking if `a.topicId` is null? – kittu Feb 01 '17 at 13:00
  • it tests for a falsy value, like `undefined`, and return `0`. – Nina Scholz Feb 01 '17 at 13:23
  • Thank you. Actually I have other requirement on top of this. I should have asked it in same question. I thought I would figure out. I posted a new question here: http://stackoverflow.com/questions/41982607/how-to-insert-values-into-object-based-on-some-id – kittu Feb 01 '17 at 14:48
3

You can create a new object that will have the topic ID for the key and the number of comments for the value

var myArray = [{
  "commentDate": "1/31/2017, 12:59:08 PM",
  "commentId": 1485594783811,
  "comments": "hi2",
  "topicId": "1485594764668",
  "userImage": "assets/img/spiritual-icon4.png",
  "username": "ki******99@gmail.com"
}, {
  "commentDate": "1/30/2017, 12:59:08 PM",
  "commentId": 1485594783812,
  "comments": "hello",
  "topicId": "1485594764669",
  "userImage": "assets/img/spiritual-icon4.png",
  "username": "ki******99@gmail.com"
}, {
  "commentDate": "1/29/2017, 12:59:08 PM",
  "commentId": 1485594783813,
  "comments": "Hi man !",
  "topicId": "1485594764668",
  "userImage": "assets/img/spiritual-icon4.png",
  "username": "ki******99@gmail.com"
}];

var result = {};

myArray.forEach(function(o){
  result[o.topicId] = result[o.topicId] || 0;
  result[o.topicId]++;
});

console.log(result);
Weedoze
  • 13,683
  • 1
  • 33
  • 63
  • Just trying to understand here. What does `|| 0` do in `result[o.topicId] || 0`. I mean why `topicId or 0`? – kittu Feb 01 '17 at 12:56
  • You are checking if topicId is null? – kittu Feb 01 '17 at 12:57
  • 1
    @kittu [This](http://stackoverflow.com/questions/5706372/what-is-the-exact-meaning-of-this-code-in-javascript) will help you understand. – ibrahim mahrir Feb 01 '17 at 13:00
  • @kittu `result[o.topicId] || 0` will get the current counter OR 0 if there is no current value – Weedoze Feb 01 '17 at 13:02
  • Hi Thanks for answer. Actually I have other requirement on top of this. I should have asked it in same question. Posted a new question. Please check once: http://stackoverflow.com/questions/41982607/how-to-insert-values-into-object-based-on-some-id – kittu Feb 01 '17 at 14:49
1

almost same as previous answers, but has less readability, but also might be a bit fast on large collections.

> a
[ { commentId: 1485594783811,
    topicId: '1485594764668',
    comments: 'hi2',
    commentDate: '1/31/2017, 12:59:08 PM',
    userImage: 'assets/img/spiritual-icon4.png',
    username: 'k****@gmail.com' },
  { commentId: 1485866129370,
    topicId: '1485853106269',
    comments: 'Hi',
    commentDate: '1/31/2017, 6:05:29 PM',
    userImage: 'assets/img/spiritual-icon4.png',
    username: 'kv****@gmail.com' },
  { commentId: 1485939547285,
    topicId: '1485853106269',
    comments: 'Hi',
    commentDate: '2/1/2017, 3:18:34 PM',
    userImage: 'assets/img/spiritual-icon4.png',
    username: 'ki*****9@gmail.com' },
  { commentId: 1485947026195,
    topicId: '1485945483238',
    comments: 'hi',
    commentDate: '2/1/2017, 4:33:46 PM',
    userImage: 'assets/img/spiritual-icon4.png',
    username: 'ki****9@gmail.com' } ]
> counts = {}
> for(var i=0; i<a.length; i++) {
... counts[a[i].topicId] = counts.hasOwnProperty(a[i].topicId) ? counts[a[i].topicId]+1 : 1;
... }
1
> counts
{ '1485594764668': 1, '1485853106269': 2, '1485945483238': 1 }
> 

a rough implementation of: http://underscorejs.org/docs/underscore.html#section-45

marmeladze
  • 6,468
  • 3
  • 24
  • 45