How can use TypeScript groupby on an array of objects by key ? For example, I have an array of car objects:
const cars = [
{ 'make': 'audi', 'model': 'r8', 'year': '2012' },
{ 'make': 'audi', 'model': 'rs5', 'year': '2013' },
{ 'make': 'ford', 'model': 'mustang', 'year': '2012' },
{ 'make': 'ford', 'model': 'fusion', 'year': '2015' },
{ 'make': 'kia', 'model': 'optima', 'year': '2012' },
];
I want to transform this array into a new object where the cars are grouped by their make:
const groupedCars = {
'audi': [
{ 'model': 'r8', 'year': '2012' },
{ 'model': 'rs5', 'year': '2013' },
],
'ford': [
{ 'model': 'mustang', 'year': '2012' },
{ 'model': 'fusion', 'year': '2015' },
],
'kia': [
{ 'model': 'optima', 'year': '2012' },
]
};
How can I achieve this in TypeScript? Is there a way to do this using lodash as well?
You can achieve this using plain TypeScript by iterating through the array and grouping objects manually.
const cars = [
{ 'make': 'audi', 'model': 'r8', 'year': '2012' },
{ 'make': 'audi', 'model': 'rs5', 'year': '2013' },
{ 'make': 'ford', 'model': 'mustang', 'year': '2012' },
{ 'make': 'ford', 'model': 'fusion', 'year': '2015' },
{ 'make': 'kia', 'model': 'optima', 'year': '2012' },
];
type Car = {
make: string;
model: string;
year: string;
};
type GroupedCars = {
[key: string]: Omit<Car, 'make'>[];
};
const groupedCars: GroupedCars = cars.reduce((acc, car) => {
if (!acc[car.make]) {
acc[car.make] = [];
}
const { make, ...rest } = car;
acc[car.make].push(rest);
return acc;
}, {} as GroupedCars);
console.log(groupedCars);
You can achieve this using plain TypeScript by iterating through the array and grouping objects manually.
Lodash provides a groupBy function which simplifies grouping objects by a key.
import _ from ‘lodash’;
const cars = [
{ 'make': 'audi', 'model': 'r8', 'year': '2012' },
{ 'make': 'audi', 'model': 'rs5', 'year': '2013' },
{ 'make': 'ford', 'model': 'mustang', 'year': '2012' },
{ 'make': 'ford', 'model': 'fusion', 'year': '2015' },
{ 'make': 'kia', 'model': 'optima', 'year': '2012' },
];
type Car = {
make: string;
model: string;
year: string;
};
type GroupedCars = {
[key: string]: Omit<Car, 'make'>[];
};
const groupedCars: GroupedCars = _.groupBy(cars, 'make');
for (const make in groupedCars) {
groupedCars[make] = groupedCars[make].map(({ make, ...rest }) => rest);
}
console.log(groupedCars);
You can define a custom function to group the array of objects based on the key.
const cars = [
{ 'make': 'audi', 'model': 'r8', 'year': '2012' },
{ 'make': 'audi', 'model': 'rs5', 'year': '2013' },
{ 'make': 'ford', 'model': 'mustang', 'year': '2012' },
{ 'make': 'ford', 'model': 'fusion', 'year': '2015' },
{ 'make': 'kia', 'model': 'optima', 'year': '2012' },
];
type Car = {
make: string;
model: string;
year: string;
};
type GroupedCars = {
[key: string]: Omit<Car, 'make'>[];
};
function groupByKey<T, K extends keyof T>(array: T[], key: K): { [key: string]: Omit<T, K>[] } {
return array.reduce((acc, item) => {
const keyValue = item[key] as unknown as string;
if (!acc[keyValue]) {
acc[keyValue] = [];
}
const { [key]: removed, ...rest } = item;
acc[keyValue].push(rest);
return acc;
}, {} as { [key: string]: Omit<T, K>[] });
}
const groupedCars: GroupedCars = groupByKey(cars, 'make');
console.log(groupedCars);