Я пытаюсь сгруппировать объекты с одинаковым свойством. Я начинаю с массива объектов и хочу закончить массивом, который содержит несколько массивов, каждый из которых содержит объекты, которые имеют одно и то же свойство.
Скажем, у меня есть этот массив объектов фильма, у каждого из них есть свойство year, и я хочу сгруппировать все фильмы с таким же свойством year в их собственный массив и, наконец, иметь все эти массивы в одном массиве.
// This is the array I've got
const films = [
{
name='film 1',
year='1992'
},
{
name='film 2',
year='1992'
},
{
name='film 3',
year='1995'
},
{
name='film 4',
year='1995'
},
{
name='film 5',
year='1995'
},
{
name='film 6',
year='1998'
},
{
name='film 7',
year='1998'
},
]
// And this is the array I want to end up with
const filmsSorted = [
[
{
name='film 1',
year='1992'
},
{
name='film 2',
year='1992'
},
]
[
{
name='film 3',
year='1995'
},
{
name='film 4',
year='1995'
},
{
name='film 5',
year='1995'
},
]
[
{
name='film 6',
year='1998'
},
{
name='film 7',
year='1998'
},
]
]
Имейте в виду, что у меня нет свойства year
заранее, и я должен динамически работать с любым годом, который я получаю в исходном массиве.
Хотя здесь много вопросов о сортировке и фильтрации массивов, я не смог найти ответ на эту конкретную проблему. Я пытался использовать reduce()
и filter()
и их комбинацию, но я просто не могу понять, как это сделать. Я нашел несколько возможных решений (преобразование его в объект и обратно в массив), но мне бы очень хотелось увидеть несколько разных способов решения этой проблемы, чтобы помочь мне лучше рассуждать об этом.
3 ответа
Просто возьмите хеш-таблицу и сгруппируйте ее по year
и возьмите значения из хеш-таблицы.
Бонус: отсортированный результат, потому что ключи объекта отсортированы, если ключи можно прочитать как индексы массива.
var films = [{ name: 'film 1', year: '1992' }, { name: 'film 2', year: '1992' }, { name: 'film 3', year: '1995' }, { name: 'film 4', year: '1995' }, { name: 'film 5', year: '1995' }, { name: 'film 6', year: '1998' }, { name: 'film 7', year: '1998' }],
grouped = Object.values(
films.reduce((r, o) => {
(r[o.year] = r[o.year] || []).push(o);
return r;
}, {})
);
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Я нашел другой способ сделать это, я оставлю это здесь на случай, если это будет полезно для будущих читателей.
const films = [{ name: 'film 1', year: '1992' }, { name: 'film 2', year: '1992' }, { name: 'film 3', year: '1995' }, { name: 'film 4', year: '1995' }, { name: 'film 5', year: '1995' }, { name: 'film 6', year: '1998' }, { name: 'film 7', year: '1998' }]
let filmsSorted = []
let years = {}
films.forEach(film => {
if (!years[film.year]) years[film.year] = []
years[film.year].push(film)
})
filmsSorted = Object.values(years)
Это создает промежуточный объект, который имеет пары ключ / значение общих свойств (лет) и массивы всех объектов, содержащих это свойство. Затем мы можем просто создать массив значений и в итоге получим требуемую сортировку.
Попробуй это:
const films = [
{
name: 'film 1',
year: '1992'
},
{
name: 'film 2',
year: '1992'
},
{
name: 'film 3',
year: '1995'
},
{
name: 'film 4',
year: '1995'
},
{
name: 'film 5',
year: '1995'
},
{
name: 'film 6',
year: '1998'
},
{
name: 'film 7',
year: '1998'
}
]
const result = films.reduce((acc, curr) => {
if (acc.some(e => e[0].year === curr.year)) acc.filter(e => e[0].year === curr.year)[0].push(curr)
else acc.push([curr])
return acc
}, [])
console.log(result)
Похожие вопросы
Новые вопросы
javascript
По вопросам программирования на ECMAScript (JavaScript / JS) и его различных диалектах / реализациях (кроме ActionScript). Включите все соответствующие теги в свой вопрос; например, [node.js], [jquery], [json] и т. д.