使用 reduce 对嵌套对象进行分组

Group nested objects with reduce

我有一个包含对象的数组

const data = [{
  "id": 19887003,
  "category": "Shops",
  "details": "Shoe Store",
  "star": 2,
  "subCategory": "Outlet",
},
{
  "id": 19234003,
  "category": "Shops",
  "details": "Shoe Point",
  "star": 2,
  "subCategory": "Outlet",
},
{
  "id": 190456003,
  "category": "Food",
  "details": "Korean",
  "star": 4,
  "subCategory": "Restaurant",
},
{
  "id": 190111003,
  "category": "Food",
  "details": "Chinese",
  "star": 4,
  "subCategory": "Restaurant",
},
{ 
  "id": 1902303,
  "category": "Food",
  "details": "Lounge",
  "star": 4,
  "subCategory": "Bar",
}]

这是一小部分,但所有对象的结构都相同:我有一个类别,有多个子类别,有时子类别有详细信息..例如类别食物有子类别餐厅,餐厅有多种类型(中文,韩文)。 我的目标是获得这样的结构:

[
   { 
      "category": "Food",
      "subCategories": [
       {
        "Subcategory": "Bar",
        "details": [
           { 
            name: "Lounge",
            star: 2,
            id: 1902303
           }
        ]
       },
       {
        "Subcategory": "Restaurant",
        "details": [
           { 
            name: "Chinese",
            star: 4,
            id: 190111003
           },
           { 
            name: "Korean",
            star: 4,
            id: 190456003
           }
        ]
       }
    },
    { 
      "category": "Shops",
      "subCategories": [
       {
        "Subcategory": "Outlet",
        "details": [
           { 
            name: "Shoe Store",
            star: 2,
            id: 19887003
           },
           { 
            name: "Shoe Point",
            star: 2,
            id: 19234003
           }
          ]
         }
       ]
    }
]

我的尝试:

const groupedCategories = data.reduce((accumulator, element) => {
  const detail = element.details;
  const category = element.category;
  const subCategory = element.subCategory;
  
    if (accumulator[category]){

    return {
      ...accumulator,
      [category]: {
        ...accumulator[category],
        subCategories: [...new Set([...accumulator[category].subCategories,subCategory])],
      }
    }}
  else {

   return {
    ...accumulator,
    [category]: {
      subCategories: [subCategory],
    }
  }
  }
  
}, {});

我试过使用这样的 reduce 方法,但这不是我想要的确切结构,尤其是如何将详细信息字段放入子类别中。 谢谢

array.reduce 似乎是正确的选择。最简单的方法是使用双 if 语句来检查前一个元素(类别和子类别是否存在)并推入现有数组或在上层创建新对象:

const data = [{
  "id": 19887003,
  "category": "Shops",
  "details": "Shoe Store",
  "star": 2,
  "subCategory": "Outlet",
},
{
  "id": 19234003,
  "category": "Shops",
  "details": "Shoe Point",
  "star": 2,
  "subCategory": "Outlet",
},
{
  "id": 190456003,
  "category": "Food",
  "details": "Korean",
  "star": 4,
  "subCategory": "Restaurant",
},
{
  "id": 190111003,
  "category": "Food",
  "details": "Chinese",
  "star": 4,
  "subCategory": "Restaurant",
},
{ 
  "id": 1902303,
  "category": "Food",
  "details": "Lounge",
  "star": 4,
  "subCategory": "Bar",
}]

let output = data.reduce((acc,cur) => {
    let {category, subCategory, ...rest} = cur;
    let prevCat = acc.find(x => x.category === category);
    if(!prevCat){
        acc.push({category, subCategories: [{subCategory, details: [rest]}]});
    } else {
        let prevSubCat = prevCat.subCategories.find(x => x.subCategory === subCategory);
        if(!prevSubCat) {
            prevCat.subCategories.push({subCategory, details: [rest]});
        } else {
            prevSubCat.details.push(rest);
        }
    }
    return acc;
}, []);

console.log(output);