Как вы groupBy массив объектов, основанных на конкретных свойствах ванильного JavaScript? Например это дано:

const products = [
  {
    category: "Sporting Goods",
    price: "$49.99",
    stocked: true,
    name: "Football"
  },
  {
    category: "Sporting Goods",
    price: "$9.99",
    stocked: true,
    name: "Baseball"
  },
  {
    category: "Sporting Goods",
    price: "$29.99",
    stocked: false,
    name: "Basketball"
  },
  {
    category: "Electronics",
    price: "$99.99",
    stocked: true,
    name: "iPod Touch"
  },
  {
    category: "Electronics",
    price: "$399.99",
    stocked: false,
    name: "iPhone 5"
  },
  { category: "Electronics", price: "$199.99", stocked: true, name: "Nexus 7" }
];

Я хочу запустить функцию Reduce, которая привела бы к новому массиву объектов, как это:

Предполагаемый результат:

const categorize = [
  {
    category:"Sporting Goods",
    products: [
      {
        name:"Football",
        price: "$49.99",
        stocked: true
      },
      {
        name:"Baseball",
        price: "$9.99",
        stocked: true
      },
      {
        name:"Basketball",
        price: "$29.99",
        stocked: true
      }
    ]
  },
  {
    category: "Electronics",
    products: [
      {
        name: "iPod Touch",
        price: "$99.99",
        stocked: true
      },
      {
        name: "iPhone 5",
        price: "$399.99",
        stocked: false
      },
      {
        name: "Nexus 7",
        price: "$199.99",
        stocked: true
      }
    ]
  }
]

Я основал свое решение из учебного руководства здесь: https://www.consolelog.io/ сгруппировать в javascript / используя функцию Reduce.

Вот мой код:

const groupBy = (arr,prop)=>{
  return arr.reduce((groups,item)=>{
    let val = item[prop];
    groups[val] = groups[val]||[];
    groups[val].push(item);
    return groups
  },{});
}

const categorize = groupBy(products,'category');
console.log(categorize);

/* returns an Object like
    Object {Sporting Goods: Array[3], Electronics: Array[3]}
   however it's not the intended output.
*/

Я пытался вернуть Object.values(obj) или Object.entries(obj) внутри функции groupBy, но он просто возвращает массив из 2 массивов, таких как [Array[3],Array[3]], и если я устанавливаю начальное значение (2-й параметр Reduce) на пустое [ ] вместо {} вывод - просто пустой массив. Нужна помощь, спасибо!

1
Twirlman 16 Авг 2019 в 12:54

2 ответа

Лучший ответ

Поскольку вам нужен массив, содержащий objects (а не просто массив простых значений), создайте объект { category, products: [] }, если он не существует в аккумуляторе:

const products=[{category:"Sporting Goods",price:"$49.99",stocked:!0,name:"Football"},{category:"Sporting Goods",price:"$9.99",stocked:!0,name:"Baseball"},{category:"Sporting Goods",price:"$29.99",stocked:!1,name:"Basketball"},{category:"Electronics",price:"$99.99",stocked:!0,name:"iPod Touch"},{category:"Electronics",price:"$399.99",stocked:!1,name:"iPhone 5"},{category:"Electronics",price:"$199.99",stocked:!0,name:"Nexus 7"}];

const output = Object.values(
  products.reduce((a, { category, ...item }) => {
    if (!a[category]) {
      a[category] = { category, products: [] };
    }
    a[category].products.push(item);
    return a;
  }, {})
);
console.log(output);
4
CertainPerformance 16 Авг 2019 в 09:58
    function (){
var map = {};
products.forEach((p) => {
  if (map[p.category]) {
 var c = p.category;
delete p.category;
  map[c].push(p);
} else {
 var c = p.category;
delete p.category;
map[c]=[c]
}
});

Object.keys(map).forEach((m) => {
ans.push({category:m, products: map[m]})
})

}

Вы можете собрать продукты за один раз и отобразить их. Затем сделайте ваш результирующий массив

0
Rahul Rana 16 Авг 2019 в 10:44