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

JS遍历nest标识父子对象数组 按展开状态收集子数据

问题说明

现有结构与下方示例中parentChildData完全一致的数组,层级规则如下:

  • nest: 0 标识父级数据
  • nest: 1 标识隶属于最近一个nest:0父节点的子级数据

遍历该数组时,需要通过遍历索引从另一个对象数组baseData中拉取对应位置的数据。业务逻辑中父节点支持展开/收起两种状态:

  • 展开状态下需要收集该父节点下的所有子数据
  • 收起状态下不收集子数据
  • 所有处于展开状态的父节点pk,存储在形如["P000", "P003"]的openRows数组中

目前已经实现两个基础规则:

  1. 始终将表头行加入结果数组
  2. 无论父节点是否展开,始终将所有父级行加入结果数组

待实现核心逻辑:当遍历到pk存在于openRows中的父节点时,需要持续将后续的子行数据加入结果数组,直到遇到下一个nest:0的父级行时停止收集。

现有未完成代码
const openRows = ["P000", "P0003"];
const newData = [];
const parentChildData = [
  [
    {
        "header": true
    },
    {
        "pk": "P000",
        "nest": 0,
        "expanded": true
    },
    {
        "pk": "P000-000",
        "nest": 1
    },
    {
        "pk": "P000-002",
        "nest": 1
    },
    {
        "pk": "P000-003",
        "nest": 1
    },
    {
        "pk": "P000-001",
        "nest": 1
    },
    {
        "pk": "P001",
        "nest": 0
    },
    {
        "pk": "P001-000",
        "nest": 1
    },
    {
        "pk": "P001-001",
        "nest": 1
    },
    {
        "pk": "P001-002",
        "nest": 1
    },
    {
        "pk": "P002",
        "nest": 0
    },
    {
        "pk": "P002-000",
        "nest": 1
    },
    {
        "pk": "P003",
        "nest": 0
    },
    {
        "pk": "P003-000",
        "nest": 1
    },
    {
        "pk": "P003-001",
        "nest": 1
    },
    {
        "pk": "P004",
        "nest": 0
    },
    {
        "pk": "P004-000",
        "nest": 1
    },
    {
        "pk": "P005",
        "nest": 0
    },
    {
        "pk": "P005-000",
        "nest": 1
    },
    {
        "pk": "P006-000",
        "nest": 0
    }
  ]
]

parentChildData.forEach((row, index) => {
    if(index === 0 && row.header) {
       // 固定加入表头行
       newData.push(baseData[index]);
    }
    if(row.nest === 0) {
       // 无论展开收起,固定加入父级行
        newData.push(row)
    }
    if(openRows.includes(row.pk)){
        // 待实现:当前父节点展开时,持续加入后续子行,直到遇到下一个nest:0的父节点
    }
})
实现方案

不需要在遇到展开父节点时嵌套向后遍历,只需加一个布尔标记位,在遍历过程中维护「当前是否需要收集子节点」的状态即可,逻辑清晰且性能更好:

  1. 初始化标记collectChild = false,用来标识当前遍历位置是否处于展开父节点的子节点区间
  2. 现有代码中parentChildData多嵌套了一层数组,实际遍历目标是内层的行数组parentChildData[0]
  3. 遍历每一行时按顺序判断:
    • 如果是表头行,直接加入baseData对应项,跳过后续逻辑
    • 如果是nest:0的父节点:先加入baseData对应项,再判断当前父节点pk是否在openRows中,更新collectChild标记为对应布尔值,跳过当前行后续逻辑
    • 如果是nest:1的子节点,且collectChild为true,加入baseData对应项即可

完整可运行代码:

const openRows = ["P000", "P003"];
const newData = [];
// 取内层实际行列表遍历
const rowList = parentChildData[0];
let collectChild = false;

rowList.forEach((_, index) => {
    const row = rowList[index];
    // 处理表头
    if (index === 0 && row.header) {
        newData.push(baseData[index]);
        return;
    }
    // 处理父级行
    if (row.nest === 0) {
        newData.push(baseData[index]);
        // 遇到新的父节点,更新子节点收集标记
        collectChild = openRows.includes(row.pk);
        return;
    }
    // 处理子级行:只有标记为需要收集时才加入
    if (row.nest === 1 && collectChild) {
        newData.push(baseData[index]);
    }
});

逻辑说明:每遇到一个父节点就重置收集标记,刚好匹配「子节点隶属于最近一个nest:0父节点」的规则,不需要额外判断子节点归属,遍历一次即可完成所有数据收集,时间复杂度O(n)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 03:24:32