
本文介绍如何在多层嵌套结构(数组内含对象,对象的 value 字段为对象数组)中,根据字符串子串(如 'ab')精准筛选出所有 name 字段包含该子串的子对象,并保持原始 key 结构,返回精简后的结果数组。
在实际开发中,我们常遇到类似这样的数据结构:一个主数组,每个元素是一个键值对对象(含 key 和 value),而 value 本身又是一个对象数组(每个子对象含 Id 和 Name)。当需要按名称模糊搜索(例如查找所有 Name 包含 'AB' 的项)时,不能简单使用 find() 或 some(),而需组合过滤、映射与重组逻辑。
核心思路是:
- 遍历外层数组;
- 对每个元素的 value 数组执行 filter(),保留 Name.includes('AB') 为 true 的子对象;
- 若筛选后 value 非空,则构造新对象(保留原 key 等属性,仅更新 value 为筛选结果)并加入结果集;
- 最终得到结构一致、内容精简的目标数组。
以下是可直接运行的完整示例代码:
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, { key, value, ...rest }) => {
const matchedItems = value.filter(item =>
typeof item.Name === 'string' && item.Name.includes(searchTerm)
);
if (matchedItems.length > 0) {
acc.push({ key, value: matchedItems, ...rest });
}
return acc;
}, []);
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() 报错;
- reduce() 初始值设为空数组 [],语义清晰且性能可控;
- 解构 { key, value, ...rest } 可兼容未来扩展字段(如 timestamp、meta 等),增强代码健壮性;
- 如需不区分大小写搜索,可将 item.Name.includes(searchTerm) 替换为 item.Name.toLowerCase().includes(searchTerm.toLowerCase())。
该方案时间复杂度为 O(n×m),其中 n 是外层数组长度,m 是各 value 数组平均长度,适用于中等规模数据;若需高频搜索或数据量极大,建议预建倒排索引或使用 Map 缓存搜索结果。










