Added grouping logic

This commit is contained in:
Franco Speziali 2022-03-16 08:55:00 +01:00
parent 6bb3226967
commit 32db96c9ad
2 changed files with 171 additions and 0 deletions

View File

@ -0,0 +1,59 @@
const EventGrouping = require("./index").default;
const { Scale } = require("../types");
const mockSortedEvents = [
{
date: new Date(2022, 3, 20),
title: "first day of spring",
},
{
date: new Date(2022, 3, 25),
title: "my birthday",
},
{
date: new Date(2022, 3, 25),
title: "buy cake for 27th",
},
{
date: new Date(2022, 3, 27),
title: "d's birthday",
},
];
console.log(EventGrouping);
describe("groupEventsByDay should", () => {
const eventGrouping = new EventGrouping(mockSortedEvents, Scale.Day);
test("generate the correct number of groups", () => {
expect(eventGrouping.groups.length).toEqual(8);
});
test("place into the same group, events that occur on the same day", () => {
expect(eventGrouping.groups[5].length).toEqual(2);
});
});
describe("groupEventsByWeek should", () => {
const eventGrouping = new EventGrouping(mockSortedEvents, Scale.Week);
test("generate the correct number of groups", () => {
expect(eventGrouping.groups.length).toEqual(2);
});
test("place into the same group, events that occur on the same week", () => {
expect(eventGrouping.groups[1].length).toEqual(3);
});
});
describe("groupEventsByMonth should", () => {
const eventGrouping = new EventGrouping(mockSortedEvents, Scale.Month);
test("generate the correct number of groups", () => {
expect(eventGrouping.groups.length).toEqual(1);
});
test("place into the same group, events that occur on the same month", () => {
expect(eventGrouping.groups[0].length).toEqual(4);
});
});

112
src/EventGrouping/index.ts Normal file
View File

@ -0,0 +1,112 @@
import {
add,
differenceInCalendarDays,
differenceInCalendarWeeks,
differenceInCalendarMonths,
} from "date-fns";
import { Event, Groups, Scale } from "../types";
export default class EventGrouping {
private readonly sortedEvents: Event[];
private readonly firstEvent: Event;
private readonly lastEvent: Event;
public readonly scale: Scale;
public readonly groups: Groups;
public static generateEmptyGroups(length: number): Groups {
const groups = [];
for (let i = 0; i <= length; i += 1) {
groups.push([]);
}
return groups;
}
constructor(sortedEvents: Event[], scale: Scale) {
this.sortedEvents = sortedEvents;
this.firstEvent = this.sortedEvents[0];
this.lastEvent = this.sortedEvents[this.sortedEvents.length - 1];
this.scale = scale;
this.groups = this.group(scale);
}
private group(scale: Scale): Groups {
switch (scale) {
case Scale.Day:
return this.byDay();
case Scale.Week:
return this.byWeek();
case Scale.Month:
return this.byMonth();
}
}
private byDay(): Groups {
const numberOfGroups = differenceInCalendarDays(
this.lastEvent.date,
this.firstEvent.date
);
return this.sortedEvents.reduce((prev, event) => {
const groupNumber = differenceInCalendarDays(
event.date,
this.firstEvent.date
);
prev[groupNumber].push(event);
return prev;
}, EventGrouping.generateEmptyGroups(numberOfGroups));
}
private byWeek(): Groups {
const numberOfGroups = differenceInCalendarWeeks(
this.lastEvent.date,
this.firstEvent.date
);
return this.sortedEvents.reduce((prev, event) => {
const groupNumber = differenceInCalendarWeeks(
event.date,
this.firstEvent.date
);
prev[groupNumber].push(event);
return prev;
}, EventGrouping.generateEmptyGroups(numberOfGroups));
}
private byMonth(): Groups {
const numberOfGroups = differenceInCalendarMonths(
this.lastEvent.date,
this.firstEvent.date
);
return this.sortedEvents.reduce((prev, event) => {
const groupNumber = differenceInCalendarMonths(
event.date,
this.firstEvent.date
);
prev[groupNumber].push(event);
return prev;
}, EventGrouping.generateEmptyGroups(numberOfGroups));
}
public getDateFromGroupIndex(index: number): Date {
const startDate = this.firstEvent.date;
switch (this.scale) {
case Scale.Day:
return add(startDate, { days: index });
case Scale.Week:
return add(startDate, { weeks: index });
case Scale.Month:
return add(startDate, { months: index });
}
}
}