关键是要让过滤逻辑清晰、可复用、不污染原始数据;根据目标选方法:叶子节点用递归+条件收集,保留结构用递归重建父子关系,多条件组用filter+some/every,深层树搜索需手写递归过滤函数。

接口返回的嵌套对象数据往往结构深、字段多、条件动态,直接硬编码遍历容易出错且难以维护。关键不是“能不能遍历”,而是“怎么让过滤逻辑清晰、可复用、不污染原始数据”。
明确过滤目标再选方法
先判断你要的是哪类过滤:
-
只取符合条件的叶子节点(比如从树形菜单中找出所有
type === "button"的按钮项)→ 用递归 + 条件收集 - 保留完整层级结构(比如搜索商品,要返回带父分类路径的结果)→ 用递归过滤并重建父子关系
-
按子数组内容筛选父对象(比如产品有
options: [{name:"Color", value:"red"}],要找含“red”且“Size”为“M”的)→ 用filter() + some()/every() -
剔除空值/无效字段(如
null、undefined、空对象、空数组)→ 用递归清理 + 类型判断
常用组合:filter + every / some 处理条件组
当后端返回类似 products 数组,每个产品含 options 子数组,而你有一组多条件(如“颜色=红 且 尺寸=M”或“颜色=蓝”),就别写多层 if。直接用:
const conditions = [
[{ name: 'Color', value: 'red' }, { name: 'Size', value: 'M' }],
[{ name: 'Color', value: 'blue' }]
];
const matched = products.filter(product =>
conditions.some(conditionGroup =>
conditionGroup.every(cond =>
product.options?.find(opt => opt.name === cond.name && opt.value === cond.value)
)
)
);
这段代码语义清晰:只要产品满足任一条件组,且该组内每个条件都在其 options 中存在,就保留。
深层结构保留:手写递归过滤函数
比如接口返回一个带 children 的分类树,你想搜产品编码 "P1001",但要求结果里包含它所在的全部父级节点(即使父节点自身没匹配)。这时 filter() 不够用,得递归构建新树:
- 对当前节点:若它本身匹配(如
id === "P1001"或code === "P1001"),保留它 - 递归处理
children,得到子匹配结果 - 若子结果非空,就把当前节点(含过滤后的 children)一起返回
- 用
Array.isArray()和typeof obj === 'object' && obj !== null安全判断结构
实际调用中建议封装成工具函数
不要把过滤逻辑写死在 .then() 里。例如:
// 工具函数示例
function filterTreeByCode(tree, targetCode, idKey = 'code', childrenKey = 'children') {
if (!Array.isArray(tree)) return [];
return tree.reduce((acc, node) => {
const matchedChildren = filterTreeByCode(node[childrenKey] || [], targetCode, idKey, childrenKey);
const hasSelfMatch = node[idKey] === targetCode;
const hasChildMatch = matchedChildren.length > 0;
if (hasSelfMatch || hasChildMatch) {
acc.push({
...node,
[childrenKey]: matchedChildren
});
}
return acc;
}, []);
}
接口拿到数据后直接调用:const result = filterTreeByCode(res.data, 'P1001');,干净、可测、可复用。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











