Typescript groupBy

Date: 2020-06-30
interface IGroup<U> {
    group: string;
    data: U;
}

export function groupBy<T, U>(array: T[], fn: (item: T) => IGroup<U>) {
    const groups: { [key: string]: U[] } = {};
    array.forEach((item) => {
        const result = fn(item);
        const group = JSON.stringify(result.group);
        groups[group] = groups[group] || [];
        groups[group].push(result.data);
    });
    return Object.keys(groups).map((group) => groups[group]);
};

// usage example:
export interface IArticleLine {
    id: string;
    articleNumber: number;
    articleName: string;
    amount: number;
    amountUnit: string;
    deliveryAmount: number;
    deliveryAmountUnit: string;
}

getArticleLines(articleLines: IArticleLine[]) {
	return groupBy(articleLines, (item) => ({ group: `${item.articleNumber}-${item.amountUnit}-${item.deliveryAmountUnit}`, data: item }))
		.map((group) => {
			const article = group[0];
			article.amount = group.reduce((_, c) => _ + c.amount || 0, 0);
			article.deliveryAmount = group.reduce((_, c) => _ + c.deliveryAmount || 0, 0);
			return article;
		})
		.map((article, i) => {
			return <div className="article-row" key={i}>
				<div>{article.articleName}</div>
				<div></div>
				<div>{`${article.amount} ${article.amountUnit}`}</div>
				<div>{`${article.deliveryAmount} ${article.deliveryAmountUnit}`}</div>
			</div>;
		});
}
37960cookie-checkTypescript groupBy