JavaScript如何根据id-parentId映射合并对象数组数据
实现方案
你当前使用的id: parentId映射结构本身可以直接支撑需求,不需要复杂改造,核心逻辑只需要先做节点索引、再按映射合并数据、最后过滤掉被合并的子节点即可,代码非常简洁:
function mergeByParentMap(ids, input) { // 构建id到节点的映射,提前拷贝data避免修改原数据 const nodeMap = Object.fromEntries( input.map(item => [item.id, { ...item, data: [...item.data] }]) ) // 记录所有需要被合并的子节点id,用于后续结果过滤 const childIdSet = new Set(Object.keys(ids)) // 遍历映射关系,将子节点数据合并到对应父节点 for (const [childId, parentId] of Object.entries(ids)) { // 父节点不存在时直接跳过,避免运行时报错 if (!nodeMap[parentId]) continue nodeMap[parentId].data.push(...nodeMap[childId].data) } // 过滤掉所有子节点,返回最终结果 return Object.values(nodeMap).filter(node => !childIdSet.has(node.id)) } // 直接调用即可得到你给出的预期output const output = mergeByParentMap(ids, input)
配置结构优化建议
如果后续业务会扩展多层嵌套合并、自定义合并规则等能力,可以把映射结构调整为parentId: childrenId[]的正向映射形式,逻辑会更直观:
// 正向映射配置示例,和你当前示例的规则完全等价 const parentChildrenMap = { "1": ["2", "3"] }
两种配置结构的适用场景对比如下:
- 反向映射(当前的
id: parentId):存储更精简,新增子节点时只需要追加单条键值对,不需要修改父节点对应的配置,适合频繁新增子节点关联、主要做子节点查父节点的场景 - 正向映射(
parentId: childrenId[]):父节点查找子节点不需要遍历全量映射,处理多层嵌套递归合并、按父节点批量配置规则时代码更简洁,适合以父节点维度做聚合操作的场景
注意:如果业务中可能出现循环关联(比如id2的父节点是id3,id3的父节点是id2),建议在合并逻辑前增加循环依赖校验,避免数据重复合并或死循环。
内容的提问来源于stack exchange,提问作者ifu66
相关产品推荐
相关产品推荐

