I have an array of objects
listOfItems: any[] = [
{text: 'Hola', group: 'espanian'},
{text: 'Hello', group: 'english'},
{text: 'How are you', group: 'english'},
{text: 'Tere', group: 'estonian'},
]
I would like to iterate over an array and create another array with categorized objects
groups: any[] = [
[
{ name: 'english',
items: [
{text: 'Hello', group: 'english'},
{text: 'How are you', group: 'english'},
]
},
{ name: 'espanian',
items: [
{text: 'Hola', group: 'espanian'}
]
},
{ name: 'estonian',
items: [
{text: 'Tere', group: 'estonian'}
]
},
]
What is the most dynamic way to do it?
The number of groups could be over 30, so I would like to avoid doing if or equals checks inside the loop
I mean dynamic – is basically without any explicit checks
like item.group = ‘english’
I have tried to achieve something similar with
let result: any = [];
this.listOfItems.forEach(p => {
var key = p.group;
result[key] = result[key] || [];
result[key].push(p);
})
however the result is not exactly what I am looking for
[
{'english': [
{text: 'Hello', group: 'english'},
{text: 'How are you', group: 'english'},
]
},
{'espanian': [
{text: 'Hola', group: 'espanian'},
]
},
]
>Solution :
- Why
any[]? - Maps are really great for these types of data manipulations. Check it out:
interface Item {
text: string;
group: string;
}
interface Categorized {
name: string;
items: Item[];
}
const itemList: Item[] = [
{ text: 'Hola', group: 'espanian' },
{ text: 'Hello', group: 'english' },
{ text: 'How are you', group: 'english' },
{ text: 'Tere', group: 'estonian' },
];
const categorize = (list: Item[]): Categorized[] => {
const map: Record<string, Categorized> = {};
list.forEach((item) => {
if (!map[item.group]) {
map[item.group] = { name: item.group, items: [item] };
return;
}
map[item.group].items.push(item);
});
return Object.values(map);
};
console.log(categorize(itemList));
We’re only using one loop.
Compiled:
var itemList = [
{ text: 'Hola', group: 'espanian' },
{ text: 'Hello', group: 'english' },
{ text: 'How are you', group: 'english' },
{ text: 'Tere', group: 'estonian' },
];
var categorize = function (list) {
var map = {};
list.forEach(function (item) {
if (!map[item.group]) {
map[item.group] = { name: item.group, items: [item] };
return;
}
map[item.group].items.push(item);
});
return Object.values(map);
};
console.log(categorize(itemList));