Reputation: 77
I'm having a bit of trouble manipulating an array of objects using underscore. I am almost there but have got stuck on attempting to combine countBy within the underscore chain.
I have the following array of objects (simplified):
var messages = [
{
id: 20,
messageHeaderId: 6,
content: "Message 1",
dateOfMessage: "2017-08-16T12:34:49.403974",
sender: "Diane"
},
{
id: 22,
messageHeaderId: 6,
content: "Latest message from MH6",
dateOfMessage: "2017-08-16T12:38:49.403974",
sender: "Diane"
},
{
id: 13,
messageHeaderId: 5,
content: "Message 1 from MH5",
dateOfMessage: "2017-08-16T10:34:23.848459",
sender: "Ora"
},
{
id: 14,
messageHeaderId: 5,
content: "Latest message from MH5",
dateOfMessage: "2017-08-16T12:37:12.237183",
sender: "Ora"
},
{
id: 15,
messageHeaderId: 5,
content: "Message 2 from MH5",
dateOfMessage: "2017-08-16T11:00:35.547921",
sender: "Ora"
},
{
id: 16,
messageHeaderId: 5,
content: "Message 3 from MH5",
dateOfMessage: "2017-08-16T11:36:51.828447",
sender: "Ora"
}
];
My goal is to return just the latest message in each thread, identified by the messageHeaderId, along with the count of messages in the thread as a new array of objects.
So from the array above this would result in an array of 2 objects that have a count property of the number of messages in each group after the groupBy method and added as a property to the returned latest messages.
This is the method I am using to sort and group the array (I'm not sure if having 2 map functions is a good idea(?) but this was the only way I managed to get this far):
var selectedMessages = _.chain(messages)
.sortBy('dateOfMessage')
.reverse()
.groupBy('messageHeaderId')
.map(function(a) {return a[0]}) // return latest message in thread
.map(function(b){
return {
content: b.content,
dateOfMessage: b.dateOfMessage,
headerId: b.messageHeaderId
// count: ??
}
})
.value();
console.log(selectedMessages);
This gives me the latest message in the thread as a new array of objects and I am just missing the count property. I have tried various combinations of _.countBy I am just not sure how to get that into the returned array.
I have created a jsfiddle here with the above code: https://jsfiddle.net/xsfs0ua0/
Upvotes: 1
Views: 869
Reputation: 26160
You need to set the count after the groupBy
, but before the first map
completes, because in that map you're returning only one record.
I've modified the fiddle: https://jsfiddle.net/xsfs0ua0/1/
Here's the relevant change:
var selectedMessages = _.chain(messages)
.sortBy('dateOfMessage')
.reverse()
.groupBy('messageHeaderId')
.map(function(a) {
// since returning only a[0], assign a new property 'count' with the size of the array
a[0]['count'] = _.size(a);
return a[0];
})
.map(function(b){...})
.value();
Upvotes: 1