Group items in Typescript with lodash
Solution 1
You can make use of the _.groupBy()
method and add a callback that returns the value you need to group it with, which is the year, month, day part of the date. You can then set the values needed by using _.map()
.
The example below uses ES6:
var meetings =
[
{date:"2001-01-01 13:00", place:"park"},
{date:"2001-01-01 14:00", place:"school"},
{date:"2001-01-02 11:00", place:"house"}
];
var result = _(meetings)
.groupBy(meeting => meeting.date.split(' ').shift())
.map((meetings, day) => ({ day, meetings }))
.value();
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
<script src="https://cdn.jsdelivr.net/lodash/4.11.2/lodash.min.js"></script>
Here is the ES5 version:
var meetings =
[
{date:"2001-01-01 13:00", place:"park"},
{date:"2001-01-01 14:00", place:"school"},
{date:"2001-01-02 11:00", place:"house"}
];
var result = _(meetings)
.groupBy(function(meeting) { return meeting.date.split(' ').shift(); })
.map(function(meetings, day) { return { day: day, meetings: meetings }; })
.value();
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
<script src="https://cdn.jsdelivr.net/lodash/4.11.2/lodash.min.js"></script>
Solution 2
If you have the typings for lodash (for newer versions of typescript do npm i --save-dev @types/lodash
), methods like _.groupBy or _.keyBy accept a generics type.
Eg: _.groupBy<TypeEachGroupCarries>(expression)
will return an array of arrays that contain items of the type TypeEachGroupCarries
.
Solution 3
Why use a library when you already have all the tools ? :)
const dateMap = meetings
.reduce(
(m, v) => {
const day = v.date.substring(0,10)
const entry = m[day]
if (typeof entry === 'undefined') {
m[day] = [v]
}
else {
entry.push(v)
}
return m
},
{}
)
const groupedMeetings = Object.keys(dateMap).map(d => {
return {
day: d,
meetings: dateMap[d]
}
})
See it running in the Typescript playground
jlp
Updated on June 01, 2020Comments
-
jlp almost 4 years
I need to group a collection of objects by date:
var meetings = [ {date:"2001-01-01 13:00", place:"park"}, {date:"2001-01-01 14:00", place:"school"}, {date:"2001-01-02 11:00", place:"house"} ];
so it becomes:
var groupedMeetings = [ { day:"2001-01-01", meetings: [ {date:"2001-01-01 13:00", place:"park"}, {date:"2001-01-01 14:00", place:"school"} ] }, { day:"2001-01-02", meetings: [ {date:"2001-01-02 11:00", place:"house"} ] } ]
I was able to group them with _.groupBy and _.map
var g = _.groupBy(meetings, function(i){return getDatePart(i.date);}); var groupedMeetings = _.map(g, function(items,key){return {day:key, meetings:items};});
But I have problems with doing the same in Typescript with https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/lodash/lodash.d.ts
First, I declared my classes:
class Meeting { date: Date, place: Meeting[] } class GroupedMeeting { constructor(private day: Date, private meetings: Meeting[]) {} }
Now I dont know which overload of groupBy to use? And how to map it to list of grouped items?
var grouped: _.Dictionary<Meeting[]> = _.groupBy(meetings, (i: Meeting) => { return this.getDatePart(i.date); }); var groupedMeetings : GroupedMeeting[] = _.map(grouped, (items: Meeting[], key: Date) => { return new GroupedMeeting (key, items); });
-
jlp about 8 yearsI got it working in JS, my issue is to write it in Typescript