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

JavaScript深度嵌套对象搜索父级属性丢失问题修复

深度嵌套对象关键词搜索实现方案

需求说明

需要在自研应用中实现对象搜索能力,支持对深度嵌套的Object执行关键词检索,返回结果需保持和输入对象完全一致的结构。
测试用示例数据如下:

const obj = {
  Cricket: {
    description: "",
    stadiums: {
      Australia: {
        Melbourne: {
          match: "IND VS ENG",
        },
        Sydney: {
          match: "BAN VS PAK",
        },
      },
      India: {
        Wankhede: {
          match: "NZ VS AUS",
        },
        Eden_Gardens: {
          match: "SA VS WI",
        },
      },
    },
  },
  Football: {
    description: "",
    stadiums: {
      UK: {
        Trafford: {
          match: "MU VS AR",
        },
        Emirates: {
          name: "LIV VS MC",
        },
      },
      Spain: {
        Wanda: {
          match: "RM VS BOC",
        },
        Santiago: {
          match: "BAR VS VIL",
        },
      },
    },
  },
};

预期效果

  • 搜索关键词Cric时,返回结果:
{
  Cricket: {
    description: '',
    stadiums: { Australia: [Object], India: [Object] }
  }
}
  • 搜索关键词tiago(匹配Santiago字段)时,返回结果:
{
  Football: {
    description: '',
    stadiums: { Spain: [Object] }
  }
}

原有代码缺陷

原有递归逻辑仅处理了值为对象的属性,当深层子节点命中搜索条件时,命中路径上父节点的非对象同级属性(比如示例中的description字段)会被直接丢弃,无法保留。
原有代码如下:

const search = (obj, text) => {
  const searchRegex = RegExp(text, 'i');
  return Object.keys(obj).reduce((acc, curr) => {
    if (searchRegex.test(curr) && typeof obj[curr] === 'object') {
      acc[curr] = obj[curr];
    } else {
      if (typeof obj[curr] === 'object') {
        const result = search(obj[curr], text);
        if (Object.keys(result).length > 0) {
          acc[curr] = result;
        }
      }
    }
    return acc;
  }, {});
};

修复后实现

修复逻辑

  • 新增命中标记:判断当前节点是否自身存在匹配的key,或存在命中搜索条件的子节点
  • 若当前key直接匹配搜索词,直接保留该key对应的完整子树,无需向下递归,减少不必要计算
  • 若当前节点被标记为命中,补全当前节点下所有非对象类型的原始属性,避免同级属性丢失
  • 新增null值判断,避免typeof null === 'object'导致的递归报错

修复后代码:

const search = (obj, text) => {
  const searchRegex = new RegExp(text, 'i');
  const result = {};
  let hasMatched = false;

  // 先遍历处理key匹配项、递归对象类型子节点
  for (const key of Object.keys(obj)) {
    const value = obj[key];
    // 当前key匹配,直接保留完整子节点
    if (searchRegex.test(key)) {
      result[key] = value;
      hasMatched = true;
      continue;
    }
    // 递归处理对象类型子节点
    if (typeof value === 'object' && value !== null) {
      const childResult = search(value, text);
      if (Object.keys(childResult).length > 0) {
        result[key] = childResult;
        hasMatched = true;
      }
    }
  }

  // 当前节点存在匹配时,补全所有非对象类型的同级属性
  if (hasMatched) {
    for (const key of Object.keys(obj)) {
      if (key in result) continue;
      const value = obj[key];
      if (typeof value !== 'object' || value === null) {
        result[key] = value;
      }
    }
  }

  return result;
};

该实现可完全符合两个场景的预期输出,命中路径上的所有父节点属性都会被完整保留,非命中分支的节点会被正确过滤。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 01:57:10