
本文介绍如何在多层嵌套结构(对象数组 → 每项含 `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 等框架的数据过滤逻辑中。










