如何从对象与数组提取值,构建以category为键的目标数组结构?
按分类重组数据并重命名字段
问题描述
我需要从data对象中提取category作为新输出对象的键,同时从listData数组中提取对应分类的字段组成数组,并将其中的title字段重命名为name。
现有数据
分类数据
const data = { "32": { "id": 32, "category": "Grocery Items", }, "33": { "id": 33, "category": "Household Items", }, }
列表数据
const listData = [ { "data": { "list": [ { "id": 1, "category_id": 32, "title": "Eggs", "category": "Grocery Items" }, { "id": 2, "category_id": 32, "title": "Bacon", "category": "Grocery Items" } ] } } ]
期望输出
const output = { "Grocery Items": [ { "id": 1, "category": "Grocery Items", "name": "Eggs", }, { "id": 2, "category": "Grocery Items", "name": "Bacon", }, ] }
原代码问题分析
你尝试的代码存在几个关键问题:
- 误用
map:map返回数组,但我们需要构建对象结构,应该用reduce。 - 解构错误:
Object.values(data)的元素只有id和category,不存在title字段,解构{title, id}会得到undefined。 - 过滤条件错误:用
item.title === title完全不匹配需求,应该通过category_id和分类的id关联数据。 - 冗余处理
listData:用forEach遍历listData并覆盖filteredList,不如一次性提取所有列表项更高效。
解决方案
下面是实现需求的正确代码:
// 提取所有嵌套的列表项到一个数组 const allItems = listData.flatMap(entry => entry.data.list); // 构建最终输出对象 const output = Object.values(data).reduce((acc, category) => { // 筛选当前分类下的所有项 const matchedItems = allItems.filter(item => item.category_id === category.id); if (matchedItems.length) { // 重命名title为name,保留其他字段 acc[category.category] = matchedItems.map(({ title, ...rest }) => ({ ...rest, name: title })); } return acc; }, {});
代码说明
- 提取列表项:用
flatMap把listData中嵌套的list数组展开,得到所有商品项的一维数组,简化后续筛选。 - 构建输出对象:用
reduce遍历每个分类,以分类名称为键,筛选出对应category_id的商品项。 - 重命名字段:通过对象解构去掉
title字段,再添加name字段并赋值为原title的值,保留其他原有字段。
内容的提问来源于stack exchange,提问作者Derek Hough
相关产品推荐
相关产品推荐

