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

JavaScript过滤嵌套对象数组 移除无P1风险项的父对象

实现嵌套数组双维度过滤

需求说明

现有对象数组结构满足以下特征:

  • 数组每个元素是父对象,包含title、rows两个属性
  • rows属性值为子对象数组,子对象包含risk属性,取值为P1、P2、P3等风险等级
    需要实现的过滤规则:
  • 子项维度:仅保留rows中risk值等于P1的行
  • 父项维度:如果某个父对象下不存在任何risk=P1的子行,直接剔除整个父对象

测试用的原始数据:

let data = [ 
    {
        "title": "QA",
        "rows": [
            {
                "risk": "P3",
                "Title": "Permission issue",
            }
        ]
    }, 
    {
        "title": "Prod",
        "rows": [
            {
                "risk": "P5",
                "Title": "Console log errors fix",
            },
            {
                "risk": "P1",
                "Title": "Server is in hung state",
            }
        ]
    }
]

预期输出结果(无P1项的QA父对象被整体剔除):

[
    {
        "title": "Prod",
        "rows": [
            {
                "risk": "P1",
                "Title": "Server is in hung state",
            }
        ]
    }
]

原有代码问题

原有实现仅使用map遍历处理父对象:

let result = input.map((obj) => ({
  ...obj,
  rows: obj.rows.filter((row) => row.risk === "P1"),
}));

问题出在map的返回数组长度和原数组完全一致,即使某个父对象过滤后rows为空数组,依然会被保留在结果中,无法实现剔除空父对象的需求。

可行实现方案

方案1:filter+map 链式调用

逻辑拆为两步,先过滤掉不符合要求的父对象,再对保留的父对象做子项过滤,逻辑清晰易读:

const result = data
  // 先筛除所有不包含P1风险行的父对象
  .filter(parent => parent.rows.some(row => row.risk === "P1"))
  // 对剩余父对象,仅保留rows里的P1风险行
  .map(parent => ({
    ...parent,
    rows: parent.rows.filter(row => row.risk === "P1")
  }))

方案2:reduce 单次遍历

只做一次数组遍历,过滤子项的同时判断是否需要保留父对象,遍历效率更高:

const result = data.reduce((res, parent) => {
  const p1Rows = parent.rows.filter(row => row.risk === "P1");
  // 存在P1行才将处理后的父对象加入结果
  if (p1Rows.length) {
    res.push({
      ...parent,
      rows: p1Rows
    })
  }
  return res;
}, []);

两种方案运行后都能得到符合预期的输出结果,可根据代码风格偏好选择。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 01:27:18