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

多级嵌套数组过滤含Gold标记的Case节点并保留父层级

解决方案:过滤嵌套数组中指定flag的Case节点并保留父级结构

需求明确

需要过滤出所有flag值为Gold的Case类型节点,同时保留这些节点所在的完整父级路径(Group、Model、Project层级),且仅Model或Project的直接子节点可能是带flag的Case。


之前方法的问题

1. Filter方法的问题

  • 直接修改原数组的cases属性,污染原数据且不符合纯函数设计原则。
  • 逻辑错误:仅对Model/Project的cases直接过滤,未递归处理Project的子Project节点,导致深层Case(如示例中的Case2)无法被正确筛选。
  • 未利用filter的返回值,递归调用时未更新节点的cases列表。

2. Reduce方法的问题

  • 未区分节点类型:对于Group/Model/Project这类父节点,仅在子节点过滤结果非空时才保留,但未正确保留父节点的完整属性(如type)。
  • 递归逻辑有误:未明确Case节点与父节点的处理边界,导致递归流程混乱,甚至出现逻辑上的无效循环。

正确实现方案

通过递归函数遍历节点,根据类型差异化处理:

  • Case类型:仅当flag匹配目标值时保留节点。
  • Group/Model/Project类型:递归处理子cases,若过滤后的子节点列表非空,则保留当前父节点(复制属性并替换cases为过滤后的列表),否则丢弃当前节点。

代码实现(TypeScript)

private getFilteredList(models: any[], targetFlag: string): any[] {
  return models.reduce((result, item) => {
    // 处理Case节点:判断flag是否匹配
    if (item.type === 'Case') {
      if (item.flag === targetFlag) {
        result.push({ ...item }); // 复制节点避免修改原数据
      }
      return result;
    }

    // 处理父级节点:递归过滤子cases
    const filteredChildren = this.getFilteredList(item.cases || [], targetFlag);
    if (filteredChildren.length > 0) {
      result.push({
        ...item,
        cases: filteredChildren
      });
    }

    return result;
  }, []);
}

代码说明

  1. 纯函数设计:不修改原数组,通过对象复制返回新的过滤结果,避免原数据被污染。
  2. 类型精准处理:明确区分Case节点与父级节点的逻辑,确保只有符合条件的Case被保留,同时完整保留其路径上的父节点。
  3. 自然终止递归:当Case节点不匹配、子节点过滤后为空时,自动终止对应分支的递归,避免无效计算。

测试验证

调用示例:

const filteredResult = this.getFilteredList(models, 'Gold');

输出结构与预期完全一致:

Group1
    ...Model1
         { Case1 }
    ...Model2
        ...Project1
             ...Project2
                 { Case2 }
        { Case4 }
Group2
    ...Model3
        { Case5 }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 16:38:21