JavaScript中按pid合并数组对象并整合coordinates属性方法
按pid分组合并坐标属性的JavaScript实现
需求说明
给定结构如下的原始数组,同pid的多条记录分别存储了coordinates下x/y/f三个字段的非空值,其余字段为null:
var originalArray = [ { pid: 1, coordinates: {x: "50", y: null, f: null} }, { pid: 1, coordinates: {x: null, y: "22", f: null} }, { pid: 1, coordinates: {x: null, y: null, f: "2"} }, { pid: 2, coordinates: {x: "23", y: null, f: null} }, { pid: 2, coordinates: {x: null, y: "62", f: null} }, { pid: 2, coordinates: {x: null, y: null, f: "15"} } ]
需要处理为每个pid仅保留一条记录,同组下所有非null的坐标字段合并到同一个coordinates对象中,目标结构如下:
[ { pid: 1, coordinates: {x: "50", y: "22", f: "2"} }, { pid: 2, coordinates: {x: "23", y: "62", f: "15"} } ]
实现方案
通用兼容版(适配字段扩展场景)
用reduce做分组聚合,遍历过程中自动合并所有非null的坐标字段,后续如果coordinates新增属性不需要修改核心逻辑:
const mergedResult = Object.values( originalArray.reduce((groupMap, currentItem) => { // 首次遇到当前pid时初始化分组结构 if (!groupMap[currentItem.pid]) { groupMap[currentItem.pid] = { pid: currentItem.pid, coordinates: {} } } // 遍历当前项的坐标字段,仅保留非null值写入分组 const groupCoord = groupMap[currentItem.pid].coordinates; Object.entries(currentItem.coordinates).forEach(([key, value]) => { if (value !== null) groupCoord[key] = value }) return groupMap }, {}) )
- 时间复杂度为O(n),仅需一次遍历原数组,数据量大时性能表现好
- 无第三方依赖,原生ES6+环境即可直接运行
- 逻辑解耦,坐标字段增减不需要调整合并逻辑
极简版(固定x/y/f字段场景)
如果确定坐标只有x/y/f三个固定字段,可以用空值运算符写更精简的代码,注意该写法需要ES2020及以上环境支持:
const mergedResult = Object.values( originalArray.reduce((groupMap, {pid, coordinates: {x, y, f}}) => { groupMap[pid] ??= {pid, coordinates: {x: null, y: null, f: null}} const target = groupMap[pid].coordinates target.x = x ?? target.x target.y = y ?? target.y target.f = f ?? target.f return groupMap }, {}) )
如果需要兼容更低版本的JS环境,把??=和??替换为对应的非空判断即可。
内容的提问来源于stack exchange,提问作者Alireza
相关产品推荐
相关产品推荐

