In Prod

← Back to Posts

GroupBy using Typescript Generics

April 06, 2020

We have needed the ability to group an array of items by the value of a property, much like the way C# LINQ works, a few times now. Below is an adaption of code taken from here.

helpers.ts

_15
/**
_15
* Groups all items in an array of objects `T` where the value of property `K` is the same
_15
* @param array Items to group
_15
* @param key Key of `T` to group by
_15
*/
_15
export function GroupBy<T, K extends keyof T>(array: T[], key: K) {
_15
let map = new Map<T[K], T[]>();
_15
array.forEach(item => {
_15
let itemKey = item[key];
_15
if (!map.has(itemKey)) {
_15
map.set(itemKey, array.filter(i => i[key] === item[key]));
_15
}
_15
});
_15
return map;
_15
}

The function takes an array of items of generic T, and a property of the items as the key K.

Here, we are taking advantage of the Map type, as well as generics and index types in typescript. The function iterates over each item to see if a key currently exists, and if it doesn't, it creates the key and adds all items that have the same value.

Example

index.ts

_33
const items = [
_33
{type: "dog", name: "fred"},
_33
{type: "cat", name: "milo"},
_33
{type: "dog", name: "otis"},
_33
{type: "duck", name: "barry"},
_33
];
_33
let grouped = GroupBy(items, "type");
_33
_33
console.log(grouped);
_33
_33
/* OUTPUT:
_33
{
_33
{
_33
key: "dog",
_33
value: [
_33
{type: "dog", name: "fred"},
_33
{type: "dog", name: "otis"},
_33
]
_33
},
_33
{
_33
key: "cat":
_33
value: [
_33
{type: "cat", name: "milo"},
_33
]
_33
},
_33
{
_33
key: "duck",
_33
value: [
_33
{type: "duck", name: "barry"},
_33
]
_33
}
_33
}
_33
*/

We can then use the returned value by iterating and accessing the key and value properties of each entry:

index.ts

_3
grouped.forEach((items, key) => {
_3
console.log(key, items);
_3
});


Andrew McMahon
These are a few of my insignificant productions
by Andrew McMahon.