Массив товаров, упорядоченных по категориям

#javascript #arrays #data-structures #mapping

#javascript #массивы #структуры данных #отображение

Вопрос:

Я пытаюсь упорядочить этот массив товаров по категориям. На данный момент я получаю количество каждой категории, но я не могу понять, как вывести этот двухмерный массив.

 let products = [
  {name: 'Tequila', category: 'drink'}, 
  {name: 'Beer', category: 'drink'}, 
  {name: 'Burger', category: 'food'},
  {name: 'Shawarma', category: 'food'}, 
  {name: 'Wine', category: 'drink'},
  {name: 'Gelatto', category: 'dessert'}
];

/*expected ouput

let arranged = [[
  {name: 'Tequila', category: 'drink'}, 
  {name: 'Beer', category: 'drink'},
  {name: 'Wine', category: 'drink'}
], [
  {name: 'Burger', category: 'food'},
  {name: 'Shawarma', category: 'food'}
], [
  {name: 'Gelatto', category: 'dessert'}
]];

*/
  

На данный момент это мой код:

 let products = [
  {name: 'Tequila', category: 'drink'}, 
  {name: 'Beer', category: 'drink'}, 
  {name: 'Burger', category: 'food'},
  {name: 'Shawarma', category: 'food'}, 
  {name: 'Wine', category: 'drink'},
  {name: 'Gelatto', category: 'dessert'}
];

let arranged = {};

products.map(x => arranged[x.category] = 1   (arranged[x.category] || 0));

console.log(arranged);  

Ответ №1:

Вы можете группировать элементы, уменьшая массив, используя объект для хранения элементов, принадлежащих к каждой категории. Чтобы получить сгруппированные категории, мы можем использовать Object.values .

 let products = [{name: 'Tequila', category: 'drink'}, 
{name: 'Beer', category: 'drink'}, 
{name: 'Burger', category: 'food'},
{name: 'Shawarma', category: 'food'}, 
{name: 'Wine', category: 'drink'},
{name: 'Gelatto', category: 'dessert'}];
const res = Object.values(
  products.reduce((acc,curr)=>(
    (acc[curr.category] = acc[curr.category] || []).push(curr), acc
  ), {})
);
console.log(res);  

Комментарии:

1. Спасибо!, это работает, Object.values выдает мне ошибку в Angular, есть ли способ использовать Object.keys вместо этого?

2. @sonEtLumiere Ты можешь попробовать let obj = products.reduce(/*...*/); let res = Object.keys(obj).map(key => obj[key]); .

Ответ №2:

Попробуйте это.Я использую Array.prototype.reduce() для группировки объектов в массиве по ключу категории, тогда вы можете получить требуемые данные с помощью Object.values()

 let products = [{
    name: 'Tequila',
    category: 'drink'
  },
  {
    name: 'Beer',
    category: 'drink'
  },
  {
    name: 'Burger',
    category: 'food'
  },
  {
    name: 'Shawarma',
    category: 'food'
  },
  {
    name: 'Wine',
    category: 'drink'
  },
  {
    name: 'Gelatto',
    category: 'dessert'
  }
];



let group = products.reduce((r, a) => {


  r[a.category] = [...r[a.category] || [], a];
  return r;
}, {});
console.log(Object.values(group));  

Ответ №3:

Я использую reducer для перехода по массиву. Для построения групп я использую массив индексов, в котором я храню категорию. Перед добавлением нового товара я смотрю, существует ли в этом массиве категория. Если это так, я беру индекс и просто добавляю в эту индексную группу элемент. В противном случае я создаю новый grup-массив, в который я добавляю товар.

 let products = [{name: 'Tequila', category: 'drink'}, 
{name: 'Beer', category: 'drink'}, 
{name: 'Burger', category: 'food'},
{name: 'Shawarma', category: 'food'}, 
{name: 'Wine', category: 'drink'},
{name: 'Gelatto', category: 'dessert'}];

let categories=[];
let res = products.reduce((new_object, current_item) => {
    index = categories.indexOf(current_item.category);

    if (index==-1) {
        categories.push(current_item.category)
        new_object.push([current_item]);
    } else {
        new_object[index].push(current_item);
    }
    return new_object;
}, []);

console.log(res);