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

React TypeScript 按条件移除多维对象内指定数组项方案

问题背景

现有多层嵌套结构的对象,需要删除对象内数组字段中符合匹配条件的指定对象片段,匹配的唯一标识符为 "menuKey": "sidebarRewards",需要给出可落地的实现方案,同时确认是否可以通过单行数组解构的方式实现,是否存在更优解法。

待移除的目标对象片段

{
  "menuKey": "sidebarRewards",
  "label": "Smart Rewards",
  "iconSetName": "narrow",
  "description": "",
  "url": "example.com/account/sidebar/index.tmpl#rewards"
}

原始对象完整结构

{
  "profile-welcome": {
    "type": "user-profile-welcome",
    "params": {
      "welcomeBack": "Welcome Back!"
    }
  },
  "sidebar-tier": {
    "type": "user-sidebar-tier",
    "params": {
      "rewardsLink": {
        "label": "REWARDS",
        "url": "/smartrewards"
      }
    }
  },
  "account-links": {
    "type": "account-links",
    "params": {
      "menu": [
        {
          "menuKey": "sidebarAccount",
          "label": "My Account",
          "iconSetName": "narrow",
          "description": "",
          "url": "example.com/account/index.tmpl"
        },
        {
          "menuKey": "sidebarSettings",
          "label": "Account Settings",
          "iconSetName": "narrow",
          "description": "",
          "url": "example.com/account/profile_preferences.tmpl"
        },
        {
          "menuKey": "sidebarRewards",
          "label": "Smart Rewards",
          "iconSetName": "narrow",
          "description": "",
          "url": "example.com/account/sidebar/index.tmpl#rewards"
        },
        {
          "menuKey": "sidebarSignOut",
          "label": "Sign Out ",
          "iconSetName": "narrow",
          "description": "",
          "url": "example.com/account/signin.tmpl?_SUBMIT=signout"
        }
      ]
    }
  },
  "showcase": {
    "type": "showcase",
    "params": {
      "brandServices": {
        "header": "SKIN SERVICES",
        "infoLink": {
          "label": "",
          "url": ""
        },
        "list": [
          {
            "showCaseKey": "firstBrandShowcase",
            "title": "Skin Services.",
            "teaser": "Our team of Consultants is at your fingertips for tips and advice.",
            "label": "See All Skin Services",
            "url": "/services"
          },
          {
            "showCaseKey": "secondBrandShowcase",
            "title": "Try on makeup.",
            "teaser": "Find your perfect shades and use your phone to try them on.",
            "label": "Select Makeup to Try On",
            "url": "/clinicalreality"
          }
        ]
      }
    }
  }
}
实现方案

针对你的需求,分场景给对应解法:
首先明确:如果你已经知道目标数组所在的固定路径(本例中就是account-links.params.menu),完全可以用展开+解构的方式实现,不需要复杂逻辑。

  • 不可变单行写法(不修改原对象,返回新对象,适合前端框架状态更新等要求不可变数据的场景)
    核心就是对路径上的每一层对象做展开,最后对目标数组用filter过滤掉匹配项,全程不会改动原始对象,代码如下:
const result = {...originalObj, 'account-links': {...originalObj['account-links'], params: {...originalObj['account-links'].params, menu: originalObj['account-links'].params.menu.filter(i => i.menuKey !== 'sidebarRewards')}}}
  • 直接修改原对象的极简写法(不需要保留原数据时用,代码最短)
originalObj['account-links'].params.menu = originalObj['account-links'].params.menu.filter(i => i.menuKey !== 'sidebarRewards')

执行完这行,目标项就直接从原数组里被移除了。

  • 通用递归写法(如果未来对象结构可能调整,你不确定目标数组的具体嵌套层级时用)
    这个方法会深度遍历整个对象的所有节点,只要是数组里存在menuKey === 'sidebarRewards'的项,都会被自动移除,不需要提前写死路径:
function deepRemoveMatch(obj, matchKey, matchVal) {
  if (Array.isArray(obj)) {
    return obj
      .filter(item => !(item?.[matchKey] === matchVal))
      .map(item => typeof item === 'object' && item !== null ? deepRemoveMatch(item, matchKey, matchVal) : item)
  }
  if (typeof obj === 'object' && obj !== null) {
    return Object.fromEntries(
      Object.entries(obj).map(([k, v]) => [k, deepRemoveMatch(v, matchKey, matchVal)])
    )
  }
  return obj
}

// 调用示例
const result = deepRemoveMatch(originalObj, 'menuKey', 'sidebarRewards')

选型建议

  • 固定结构的常规场景直接选第一种不可变写法就行,逻辑清晰,没有副作用,后续维护的人一眼能看懂改了什么
  • 小脚本、不需要保留原对象的场景直接用第二种写法,最省事
  • 只有结构动态变化、无法提前确定路径的时候再用递归方案,性能比固定路径写法稍差,但是通用性最强

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 01:01:43