JavaScript: группируем массив объектов
создаем функцию для группировки объектов в массиве
В этой небольшой статье мы разберем, как создать собственную функцию группировки объектов в массиве по одному свойству.
Исходный массив:
const albums = [
{
artist: "Pearl Jam",
album: "Ten",
year: "1991"
},
{
artist: "Pearl Jam",
album: "Yield",
year: "1998"
},
{
artist: "Soundgarden",
album: "Badmotorfinger",
year: "1991"
},
{
artist: "Soundgarden",
album: "Superunknown",
year: "1994"
}
];
Мы хотим сгруппировать объекты массива, например, по свойству artist
или years
.
Результат
Группировка по years
{
1991: [
{
{
artist: 'Pearl Jam',
album: 'Ten',
year: '1991',
},
{
artist: 'Soundgarden',
album: 'Badmotorfinger',
year: '1991',
},
}
],
1994: [
{
artist: 'Soundgarden',
album: 'Superunknown',
year: '1994',
},
],
1998: [
{
artist: 'Pearl Jam',
album: 'Yield',
year: '1998',
},
]
}
Группировка по artist
{
'Pearl Jam': [
{
artist: 'Pearl Jam',
album: 'Ten',
year: '1991',
},
{
artist: 'Pearl Jam',
album: 'Yield',
year: '1998',
},
],
'Soundgarden': [
{
artist: 'Soundgarden',
album: 'Badmotorfinger',
year: '1991',
},
{
artist: 'Soundgarden',
album: 'Superunknown',
year: '1994',
},
]
}
Реализация
function groupBy(key) {
return function group(array) {
return array.reduce((acc, obj) => {
const property = obj[key];
acc[property] = acc[property] || [];
acc[property].push(obj);
return acc;
}, {});
};
}
const groupByYear = groupBy("year");
groupByyear(albums);
const groupByArtist = groupBy("artist");
groupByArtist(albums);
Объяснение
groupBy
- функция-обертка с каррированием, в качестве единственного аргумента получает наименование свойства, по которому будет осуществляться группировка.
Функция groupBy
возвращает другую функцию group
, аргументом которой является группируемый массив.
В свою очередь, функция group
применяет к исходному массиву метод reduce и использует пустой массив в качестве аккумулятроа (именно в этот массив будет записываться нужный нам результат).
Внутри reduce
укажем, что ключом для группировки объектов является свойство year
и массив-аккумулятор acc
является пустым, то есть не содержит никаких пар “ключ - значение”:
const property = obj[key];
// obj[key], например '1991'.
acc[property] = acc[property] || [];
// в этот момент acc['1991'] еще не существует и массив acc является пустым. Этот шаг важен, так как происходит проверка: существует ли acc['1991'] и, если не существует, он создается, принимая в качестве значения пустой массив
acc[property].push(obj);
// здесь мы помещаем объекты, соответствующие условию, в целевую группу
Спасибо за внимание.
Перевод статьи Nikhil Vijayan “How to Group an array of objects in JavaScript”.