0

我正在尝试将对象数组转换为如下形式:

const categories = [{
    "category": "Category 1",
    "desc": "Description 1 of the category 1"
  },
  {
    "category": "Category 1",
    "desc": "Description 2 of the category 1"
  }, {
    "category": "Category 2",
    "desc": "Description 1 of the category 2"
  },
  {
    "category": "Category 2",
    "desc": "Description 2 of the category 2"
  },
  {
    "category": "Category 3",
    "desc": "Description 1 of the category 3"
  }, {
    "category": "Category 3",
    "desc": "Description 2 of the category 3"
  }
];

到表格(所需的结果集);

[
  {
    "category": "Category 1",
    "desriptionList": [
      {
        "desc": "Description 1 of the category 1"
      },
      {
        "desc": "Description 2 of the category 1"
      }
    ]
  },
  {
    "category": "Category 2",
    "desriptionList": [
      {
          "error": "Description 1 of the category 2"
      },
      {
          "error": "Description 2 of the category 2"
      },
    ]
  },
   {
    "category": "Category 3",
    "desriptionList": [
      {
          "error": "Description 1 of the category 3"
      },
      {
          "error": "Description 2 of the category 3"
      },
    ]
  }
]

使用reduce方法:

const result = categories.reduce((acc, item) => {
  return [{
    ...acc,
    'category': item.category,
    'desriptionList': item.desc
  }]
}, [])

但似乎我以错误的方式和错误的位置使用累加器,因为有一个奇怪的输出;

[{
  0: {
    0: { ... },
    category: "Category 3",
    desriptionList: "Description 1 of the category 3"
  },
  category: "Category 3",
  desriptionList: "Description 2 of the category 3"
}]

密码笔

4

3 回答 3

1

保持简单并使用 Array.reduce() 和 Array.findIndex 遍历每个对象,并决定是否应将其数据添加到累加器中的现有对象,或者是否应创建并推送新对象。

const categories=[{category:"Category 1",desc:"Description 1 of the category 1"},{category:"Category 1",desc:"Description 2 of the category 1"},{category:"Category 2",desc:"Description 1 of the category 2"},{category:"Category 2",desc:"Description 2 of the category 2"},{category:"Category 3",desc:"Description 1 of the category 3"},{category:"Category 3",desc:"Description 2 of the category 3"}];

const result = categories.reduce(( acc, cur ) => {
  let idx = acc.findIndex( obj => obj.category === cur.category )
  if( idx > -1 )
  {
    acc[idx].descriptionList.push(cur.desc)
  }
  else
  {
    acc.push( { category: cur.category, descriptionList: [ cur.desc ] } )
  }
  
  return acc
}, [])

console.log(result)

于 2020-10-25T21:01:17.140 回答
1

“!target.descriptionList.includes(curr)”条件确保每个类别没有重复的 desc。如果您觉得没有必要,请随意删除它。

const categories = [{
    "category": "Category 1",
    "desc": "Description 1 of the category 1"
  },
  {
    "category": "Category 1",
    "desc": "Description 2 of the category 1"
  }, {
    "category": "Category 2",
    "desc": "Description 1 of the category 2"
  },
  {
    "category": "Category 2",
    "desc": "Description 2 of the category 2"
  },
  {
    "category": "Category 3",
    "desc": "Description 1 of the category 3"
  }, {
    "category": "Category 3",
    "desc": "Description 2 of the category 3"
  }
];

const newArr = categories.reduce((acc, curr) => {
    let target = acc.find(element => element.category === curr.category);

    if (target) {
        if (!target.descriptionList.includes(curr)) {
            delete curr.category;
            target.descriptionList.push(curr);
        }
    } else {
        acc.push({
            category: curr.category,
            descriptionList: [{ desc: curr.desc }]
        })
    }

    return acc
}, []);

console.log('newArr: ' + JSON.stringify(newArr));

输出

newArr: [
  {
    "category": "Category 1",
    "descriptionList": [
      {
        "desc": "Description 1 of the category 1"
      },
      {
        "desc": "Description 2 of the category 1"
      }
    ]
  },
  {
    "category": "Category 2",
    "descriptionList": [
      {
        "desc": "Description 1 of the category 2"
      },
      {
        "desc": "Description 2 of the category 2"
      }
    ]
  },
  {
    "category": "Category 3",
    "descriptionList": [
      {
        "desc": "Description 1 of the category 3"
      },
      {
        "desc": "Description 2 of the category 3"
      }
    ]
  }
]
于 2020-10-25T21:19:43.783 回答
0

由于您需要使用对desc类别进行分组,因此您将使用一个对象作为累加器。在每次迭代中,将累加器 ( acc) 传播到一个新对象中,并添加当前的category.

要创建或更新类别的对象,请添加category, 并传播该类别的前一个实例(undefined被忽略),添加desriptionList,并传播前一个实例desriptionList(如果没有,则为后备),然后添加当前desc项目。

使用 转换为数组Object.values()

const categories = [{"category":"Category 1","desc":"Description 1 of the category 1"},{"category":"Category 1","desc":"Description 2 of the category 1"},{"category":"Category 2","desc":"Description 1 of the category 2"},{"category":"Category 2","desc":"Description 2 of the category 2"},{"category":"Category 3","desc":"Description 1 of the category 3"},{"category":"Category 3","desc":"Description 2 of the category 3"}];

const result = Object.values(categories.reduce((acc, { category, desc }) => ({
  ...acc,
  [category]: {
    ...acc[category],
    category,
    desriptionList: [
      ...(acc[category]?.desriptionList || []),
      { desc }
    ]
  }
}), {}))

console.log(result)

另一种选择是将类别分组到 Map,然后将 Map 转换为带有Array.from().

const categories = [{"category":"Category 1","desc":"Description 1 of the category 1"},{"category":"Category 1","desc":"Description 2 of the category 1"},{"category":"Category 2","desc":"Description 1 of the category 2"},{"category":"Category 2","desc":"Description 2 of the category 2"},{"category":"Category 3","desc":"Description 1 of the category 3"},{"category":"Category 3","desc":"Description 2 of the category 3"}];

const result = Array.from(
    categories.reduce((acc, { category, desc }) => {
    if (!acc.has(category)) acc.set(category, []); // initialize the category with an empty array

    acc.get(category).push({ desc }) // push current desc into the array

    return acc;
  }, new Map()), 
  ([category, desriptionList]) => ({ category, desriptionList }) // convert to an array
)

console.log(result)

于 2020-10-25T20:55:15.563 回答