
本文介绍如何在多层嵌套结构(对象数组 → value 属性为对象数组)中,根据子对象的 `name` 字段模糊匹配指定字符串(如 `'ab'`),并精准返回符合条件的顶层对象及其精简后的 `value` 子数组。
在实际开发中,我们常遇到类似如下结构的数据:一个顶层数组,每个元素是一个包含 key 和 value 属性的对象,而 value 又是一个对象数组(每个子对象含 Id 和 Name 字段)。当需要按 Name 模糊搜索(例如查找包含 'AB' 的项)时,目标不是简单地扁平化所有数据,而是保留原始层级关系——仅筛选出至少有一个 Name 匹配的顶层对象,并将其 value 数组压缩为仅含匹配项的子集。
实现这一需求的核心思路是:
- 使用 Array.prototype.reduce() 遍历顶层数组,累积构建结果;
- 对每个元素的 value 数组,用 filter() + String.prototype.includes() 筛选 Name 包含目标字符串的子对象;
- 仅当筛选后 found.length > 0 时,才将当前顶层对象({...item, value: found})推入结果数组。
以下是完整可运行示例:
const data = [
{ "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" }] }
];
const searchTerm = 'AB';
const result = data.reduce((acc, { value, ...rest }) => {
const matchedItems = value.filter(item => item.Name.includes(searchTerm));
if (matchedItems.length > 0) {
acc.push({ ...rest, value: matchedItems });
}
return acc;
}, []);
console.log(result);
// 输出:
// [
// { "key": "112", "value": [{ "Id": "3424", "Name": "ABC" }] },
// { "key": "222", "value": [{ "Id": "2312", "Name": "ABD" }] }
// ]✅ 关键优势说明:
- 保持原始数据结构完整性,不破坏 key 与筛选后 value 的映射关系;
- 支持大小写敏感搜索(如需忽略大小写,可改用 item.Name.toLowerCase().includes(searchTerm.toLowerCase()));
- 时间复杂度为 O(n×m),其中 n 是顶层数组长度,m 是各 value 数组平均长度,适用于中等规模数据;
- 无副作用,纯函数式风格,便于测试与复用。
⚠️ 注意事项:
- 若需精确匹配(而非包含),请将 includes() 替换为 === 或正则 new RegExp(^${searchTerm}$);
- 若 value 可能为 null 或 undefined,建议在 filter 前增加空值校验(如 Array.isArray(value) && value.filter(...));
- 浏览器兼容性良好(ES2015+),现代前端项目可直接使用;若需兼容旧环境,可用 Babel 转译或改写为传统 for 循环。
该方案简洁、健壮且语义清晰,是处理此类嵌套搜索任务的推荐实践。










