To accomplish this task, you can utilize the Array#reduce
method, which converts an array into a single value:
interface Person {
id: string;
name: string;
profession: string;
}
interface GroupedPerson extends Omit<Person, "profession"> {
professions: Array<Person["profession"]>;
}
const people: Array<Person> = [
{
id: "1",
name: "John Doe",
profession: "engineer",
},
{
id: "2",
name: "Jane Smith",
profession: "manager",
},
{
id: "3",
name: "Alice Johnson",
profession: "artist",
},
];
const groupedPeople = people.reduce<Array<GroupedPerson>>(
(groupedPersons, currentPerson) => {
const matchingGroupedPersonIndex = groupedPersons.findIndex(
(g) => g.id === currentPerson.id
);
if (matchingGroupedPersonIndex === -1) { // Add the person to the array if not encountered yet
groupedPersons.push({
id: currentPerson.id,
name: currentPerson.name,
professions: [currentPerson.profession],
});
} else { // Otherwise, add their profession
groupedPersons[matchingGroupedPersonIndex].professions.push(currentPerson.profession);
}
return groupedPersons;
},
[]
);
groupedPeople
will contain the following structure:
[
{
"id": "1",
"name": "John Doe",
"professions": [
"engineer"
]
},
{
"id": "2",
"name": "Jane Smith",
"professions": [
"manager"
]
},
{
"id": "3",
"name": "Alice Johnson",
"professions": [
"artist"
]
}
]