Skip to content

Instantly share code, notes, and snippets.

@reidev275
Created December 13, 2019 18:00
Show Gist options
  • Save reidev275/83791aca6b3d9f6c7db6f1617e0a1a4d to your computer and use it in GitHub Desktop.
Save reidev275/83791aca6b3d9f6c7db6f1617e0a1a4d to your computer and use it in GitHub Desktop.
type Monoid<A> = { empty: A; append: (x: A, y: A) => A };
const sum: Monoid<number> = { empty: 0, append: (x, y) => x + y };
interface OrderType {
period: "ytd" | "mtd";
orders: number;
}
const data: OrderType[] = [
{ period: "ytd", orders: 3 },
{ period: "ytd", orders: 5 },
{ period: "mtd", orders: 2 }
];
type Pivot<K extends string, T extends { [s in K]: any }> = {
[P in keyof Omit<T, K>]: { [A in T[K]]: T[P] }
};
const p: Pivot<"period", OrderType> = { orders: { mtd: 0, ytd: 0 } };
const b = (M: Monoid<number>) => ({
orders: data.reduce(
(acc, x) => ({
...acc,
[x.period]: M.append(acc[x.period] || M.empty, x.orders)
}),
<any>{}
)
});
const order = (ytd: number, mtd: number): Pivot<"period", OrderType> => ({
orders: { ytd, mtd }
});
const sumOrders: Monoid<Pivot<"period", OrderType>> = {
empty: { orders: { ytd: 0, mtd: 0 } },
append: (x: Pivot<"period", OrderType>, y) => {
console.log(x);
console.log(y);
return {
orders: {
ytd: x.orders.ytd + y.orders.ytd,
mtd: x.orders.ytd + y.orders.mtd
}
};
}
};
const pivotOn = <K extends string, T extends { [s in K]: any }>(
columnName: K,
collection: T[],
M: Monoid<Pivot<K, T>>
): Pivot<K, T> =>
collection.reduce((p, t) => {
// need to pivot the t into a Pivot<K, T>
const x = Object.keys(t)
.filter(k => k !== columnName)
.reduce((acc, key) => {
const keyofT = key as keyof T
return { ...acc, [key]: { ...acc[keyofT]: t[keyofT] }}
}, M.empty)
return M.append(p, x);
}, M.empty);
const res = pivotOn("period", data, sumOrders);
console.log(res);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment