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

如何将表格对应的对象数组转换为嵌套树形结构JSON?

JS平面对象数组转指定层级树形结构实现方案

核心思路

你的需求本质是按照a -> b -> c的固定层级优先级,把平面的对象字段逐层折叠成嵌套结构,每一层没有后续子字段时赋值为null,有子字段时用数组承载多个子节点即可。

分步实现逻辑

  • 先定义固定的层级顺序数组,后续要新增层级只要改这个数组就行,无需调整核心逻辑
  • 初始化空对象作为最终输出结果
  • 遍历原数组的每一个平面对象:
    • 从第一层开始依次取当前层级对应的字段值,无值则直接终止当前对象的处理
    • 逐层判断当前层级的key是否已存在于上级结构中,不存在则按规则初始化结构:还有下一级字段时初始化为空数组,无下一级字段时赋值为null
    • 遇到当前对象没有下一层级字段的情况,直接终止遍历,无需处理更深层级

可运行代码示例

首先修正你原数组的写法(a1等属于字符串值,需要加引号避免变量未定义报错),转换代码如下:

// 原数据修正版
const objects = [
  {a: 'a1', b: 'b1', c: 'c1'},
  {a: 'a1', b: 'b2'},
  {a: 'a1'},
  {a: 'a2', b: 'b1'},
  {a: 'a3'}
]
// 定义层级顺序,按要求是a→b→c
const levelKeys = ['a', 'b', 'c']
const result = {}

objects.forEach(item => {
  // 记录当前遍历到的父级节点
  let parent = result
  for (let i = 0; i < levelKeys.length; i++) {
    const key = levelKeys[i]
    const curVal = item[key]
    // 当前层级无值,直接结束
    if (!curVal) break
    const nextKey = levelKeys[i + 1]
    const hasNext = !!nextKey && !!item[nextKey]
    // 最后一层没有下一级,直接赋值null
    if (!hasNext) {
      // 父级是数组的情况
      if (Array.isArray(parent)) {
        // 检查数组里有没有已经存在当前key的对象
        const exist = parent.find(p => Object.prototype.hasOwnProperty.call(p, curVal))
        if (!exist) parent.push({[curVal]: null})
      } else {
        // 父级是对象的情况(第一层a的父级是result对象)
        if (!parent[curVal]) parent[curVal] = null
      }
      break
    }
    // 有下一级,需要初始化数组
    if (Array.isArray(parent)) {
      let existNode = parent.find(p => Object.prototype.hasOwnProperty.call(p, curVal))
      if (!existNode) {
        existNode = {[curVal]: []}
        parent.push(existNode)
      }
      parent = existNode[curVal]
    } else {
      if (!parent[curVal]) parent[curVal] = []
      parent = parent[curVal]
    }
  }
})

// 输出结果
console.log(JSON.stringify(result, null, 4))

运行上述代码输出的结构和你要求的完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 17:54:02