1

I'm trying to understand how the reduce method work. The groupBy function only return object that is grouped by category. How do I get the wanted result below? I have tried many ways but none works.

const PRODUCTS = [
  { category: "Fruits", price: "$1", stocked: true, name: "Apple" },
  { category: "Fruits", price: "$1", stocked: true, name: "Dragonfruit" },
  { category: "Fruits", price: "$2", stocked: false, name: "Passionfruit" },
  { category: "Vegetables", price: "$2", stocked: true, name: "Spinach" },
  { category: "Vegetables", price: "$4", stocked: false, name: "Pumpkin" },
  { category: "Vegetables", price: "$1", stocked: true, name: "Peas" },
];

function groupBy(objectArray, property) {
  return objectArray.reduce((previousResult, currentValue) => {
    const key = currentValue[property];
    const curGroup = previousResult[key] ?? [];

    return { ...previousResult, [key]: [...curGroup, currentValue] };
  }, {});
}

console.log(groupBy(PRODUCTS, "category"));
.as-console-wrapper { max-height: 100% !important; }
const wantedResult = [
  {
    category: "Fruits",
    item: [
      { category: "Fruits", price: "$1", stocked: true, name: "Apple" },
      { category: "Fruits", price: "$1", stocked: true, name: "Dragonfruit" },
      { category: "Fruits", price: "$2", stocked: false, name: "Passionfruit" },
    ],
  },
  {
    category: "Fruits",
    item: [
      { category: "Fruits", price: "$1", stocked: true, name: "Apple" },
      { category: "Fruits", price: "$1", stocked: true, name: "Dragonfruit" },
      { category: "Fruits", price: "$2", stocked: false, name: "Passionfruit" },
    ],
  },
];
Phil
  • 157,677
  • 23
  • 242
  • 245
DanNg
  • 45
  • 3

1 Answers1

3

Assuming you want a result including vegetables and not just fruits duplicated, extract the entries from the grouped object and map them to the new format

// Just your code minified
const PRODUCTS=[{category:"Fruits",price:"$1",stocked:!0,name:"Apple"},{category:"Fruits",price:"$1",stocked:!0,name:"Dragonfruit"},{category:"Fruits",price:"$2",stocked:!1,name:"Passionfruit"},{category:"Vegetables",price:"$2",stocked:!0,name:"Spinach"},{category:"Vegetables",price:"$4",stocked:!1,name:"Pumpkin"},{category:"Vegetables",price:"$1",stocked:!0,name:"Peas"},];function groupBy(e,t){return e.reduce((e,r)=>{let c=r[t],a=e[c]??[];return{...e,[c]:[...a,r]}},{})}

const wantedResult = Object.entries(groupBy(PRODUCTS, "category")).map(
  // Map each "category" key and "item" array value pair
  // to an object with "category" and "item" properties
  ([category, item]) => ({ category, item })
);


console.log(wantedResult);
.as-console-wrapper { max-height: 100% !important; }
Phil
  • 157,677
  • 23
  • 242
  • 245