You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript 转换合并同结构JSON对象为指定嵌套结构方法

嵌套对象同路径值合并问题

需求说明

假设给定如下JSON对象:

{
    "a": {
        "title": {
            "text": "text a"
        }
    },
    "b": {
        "title": {
            "text": "text b"
        }
    }
}

需要转换合并为如下目标结构:

{
    "title": {
        "text": {
            "a": "text a",
            "b": "text b"
        }
    }
}

第二个示例:给定3个结构完全一致的对象aObject、bObject、cObject:

let aObject = {
    "level1": {
        "level2": {
            "level3": "text a"
        }
    }
}
let bObject = {
    "level1": {
        "level2": {
            "level3": "text b"
        }
    }
}
let cObject = {
    "level1": {
        "level2": {
            "level3": "text c"
        }
    }
}

需要合并为如下结构:

{
    "level1": {
        "level2": {
            "level3": {
                "aObject": "text a",
                "bObject": "text b",
                "cObject": "text c"
            }
        }
    }
}

这类操作没有通用的标准专业术语,核心逻辑是递归遍历所有源对象的嵌套路径,将相同路径下的叶子节点值,以源对象的键名为属性名收集到同一层对象中,实现复杂度低,属于常规的嵌套对象处理场景。

现有可运行实现

提问者已经完成了基础版本的实现,希望得到更简洁的写法,现有代码如下:

let object = {
    "a": {
        "title": {
            "text": "text a"
        }
    },
    "b": {
        "title": {
            "text": "text b"
        }
    }
}

function reduce(node, object, result = {}) {
    for (let key in object) {
        if (typeof result[key] === 'undefined') {
            result[key] = {}
        }

        if (typeof object[key] === 'string') {
            result[key][node] = object[key]

        } else {
            reduce(node, object[key], result[key])
        }
    }

    return result
}

let result = Object.entries(object).reduce((result, [key, value]) => {
    return reduce(key, value, result)
}, {})

console.log(result)

精简实现方案

可以将递归逻辑和入口合并,减少冗余参数,同时兼容两个示例的使用场景:

const mergeNested = (...entries) => entries.reduce((res, [rootKey, obj]) => {
  const dive = (target, currentNode) => {
    Object.entries(currentNode).forEach(([key, val]) => {
      if (typeof val === 'object' && val !== null) {
        target[key] ??= {}
        dive(target[key], val)
      } else {
        target[key] ??= {}
        target[key][rootKey] = val
      }
    })
  }
  dive(res, obj)
  return res
}, {})

// 第一个示例调用方式
const demo1Obj = {
  "a": {"title": {"text": "text a"}},
  "b": {"title": {"text": "text b"}}
}
console.log(mergeNested(...Object.entries(demo1Obj)))

// 第二个示例调用方式
const aObject = {"level1": {"level2": {"level3": "text a"}}}
const bObject = {"level1": {"level2": {"level3": "text b"}}}
const cObject = {"level1": {"level2": {"level3": "text c"}}}
console.log(mergeNested(
  ['aObject', aObject],
  ['bObject', bObject],
  ['cObject', cObject]
))

方案特点:

  • 用??=空值赋值运算符替代手动判断属性是否为undefined的冗余代码
  • 递归遍历逻辑内聚,不需要额外传递临时结果对象作为参数
  • 兼容任意数量、任意嵌套深度的源对象,只要所有源对象的非叶子节点路径完全一致即可正常合并
  • 适配两种使用场景:第一种直接拆分源对象的键值对传入即可,第二种手动传入自定义键名和源对象的组合即可,不需要额外修改逻辑
  • 增加了val !== null的判断,避免null值被误判为对象进入递归导致报错

内容的提问来源于stack exchange,提问作者Muhammet Ilendemli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 17:12:32