如何在嵌套数组对象中按名称模糊搜索字符

本文介绍如何在多层嵌套结构(对象数组 → 每项含 `value` 数组 → 数组内为带 `name` 字段的对象)中,高效筛选出 `name` 包含指定子字符串(如 `'ab'`)的所有匹配项,并保持原始键结构。

在实际开发中,我们常遇到类似这样的数据结构:一个对象数组,每个对象包含 key 和 value 字段,其中 value 是一个对象数组,而每个子对象都有 Name 属性。当需要根据用户输入(例如搜索关键词 'AB')进行跨层级模糊匹配时,不能仅用简单遍历,而需结合函数式方法精准过滤与重构。

核心思路是:

  • 遍历外层数组(arr);
  • 对每个元素的 value 子数组执行 .filter(),保留 Name 包含目标字符串的项;
  • 若筛选后子数组非空,则将当前外层对象(除 value 外)与新 value 重新组合;
  • 最终返回结构一致、仅含匹配结果的新数组。

以下是完整可运行示例代码:

const arr = [
  { "key": "001", "value": [{ "Id": "2345", "Name": "Test" }] },
  { "key": "112", "value": [{ "Id": "1234", "Name": "UHV" }, { "Id": "3424", "Name": "ABC" }] },
  { "key": "222", "value": [{ "Id": "2312", "Name"

: "ABD" }, { "Id": "1321", "Name": "RFV" }, { "Id": "4567", "Name": "ERF" }] } ]; function searchByName(array, keyword) { return array.reduce((result, { value, ...rest }) => { const matchedItems = value.filter(item => typeof item.Name === 'string' && item.Name.includes(keyword) ); if (matchedItems.length > 0) { result.push({ ...rest, value: matchedItems }); } return result; }, []); } // 使用示例 const result = searchByName(arr, 'AB'); console.log(JSON.stringify(result, null, 2)); // 输出: // [ // { // "key": "112", // "value": [{ "Id": "3424", "Name": "ABC" }] // }, // { // "key": "222", // "value": [{ "Id": "2312", "Name": "ABD" }] // } // ]

注意事项

  • 使用 typeof item.Name === 'string' 做类型防护,避免 undefined 或非字符串值调用 .includes() 报错;
  • String.prototype.includes() 区分大小写;如需忽略大小写,可改用 item.Name.toLowerCase().includes(keyword.toLowerCase());
  • 若需支持正则高级匹配(如词首匹配、全字匹配),可将 includes() 替换为 RegExp.test();
  • 此方案时间复杂度为 O(n×m),适用于中等规模数据;若数据量极大且高频搜索,建议预建索引或使用 Map 缓存。

该逻辑简洁、可复用、无副作用,符合现代 JavaScript 函数式编程规范,可直接集成至 React/Vue 等框架的数据过滤逻辑中。