如何对对象数组按属性分组并将各组内数据扁平合并为单一数组
解决数组分组后扁平化数据的问题
我来帮你搞定这个问题!你当前代码的核心问题是没有展开nextVal.data.map返回的数组,导致每次迭代都把整个label数组作为单个元素加入分组数组,最终形成了嵌套结构。只需要做一个很小的改动,就能在现有reduce函数的基础上实现你要的扁平合并效果。
修正后的重构函数
const arrToRestructure = [ { x: "test-x1", y: "test-y1", data: [ {id: 1, label: "label-y1-1"}, {id: 2, label: "label-y1-2"} ] }, { x: "test-x2", y: "test-y1", data: [ {id: 1, label: "label-y1-3"}, {id: 2, label: "label-y1-4"} ] }, { x: "test-x2", y: "test-y2", data: [ {id: 1, label: "label-y2-1"}, {id: 2, label: "label-y2-2"} ] }, ]; const restructureArr = () => { const restructuredArr = arrToRestructure.reduce( (prevVal, nextVal) => ({ ...prevVal, [nextVal["y"]]: [ ...(prevVal[nextVal["y"]] || []), // 保留当前分组的已有数据 ...nextVal.data.map(item => item.label) // 展开map返回的label数组,避免嵌套 ] }), {}); return restructuredArr; };
测试输出结果
{ "test-y1": [ "label-y1-1", "label-y1-2", "label-y1-3", "label-y1-4" ], "test-y2": [ "label-y2-1", "label-y2-2" ] }
关键改动说明
...(prevVal[nextVal["y"]] || []):如果当前y属性对应的分组已经存在,就展开它的已有元素;如果是第一次处理该分组,就用空数组作为初始值。...nextVal.data.map(item => item.label):map会生成一个包含当前项所有label的新数组,加上...展开运算符后,这个数组里的每个元素都会被单独添加到分组数组中,而不是把整个数组作为单个元素插入,这样就避免了嵌套结构。
这个改动完全复用了你原有的reduce逻辑,后续如果需要调整提取的字段(比如从label改成id),只需要修改map里的返回值即可,扩展性很好。
内容的提问来源于stack exchange,提问作者D.Wasilewski
相关产品推荐
相关产品推荐

