JavaScript数组Filter方法问题:如何过滤对象中的嵌套数组
解决对象数组的双层过滤问题
你的问题出在:当前代码只筛选出了包含符合条件fruit的对象,但没有修改对象内部的fruit数组,所以输出的对象还是保留了原始的fruit内容。要实现目标结果,需要同时完成两个操作:筛选符合条件的对象,并且修改这些对象的fruit数组为过滤后的结果。
方案一:filter + map 组合(直观易懂)
const elements = ['apple']; const objects = [ { id: 1, fruit:[{"name": "apple" },{"name": "banana" }]}, { id: 2, fruit:[{"name": "apple" },{"name": "orange" }]}, { id: 3, fruit:[{"name": "orange" },{"name": "banana" }]}, { id: 4, fruit:[{"name": "orange" },{"name": "banana" }]} ]; const results = objects // 第一步:筛选出至少有一个符合条件fruit的对象 .filter(obj => obj.fruit.some(ele => elements.includes(ele.name))) // 第二步:对每个保留的对象,过滤其fruit数组 .map(obj => ({ ...obj, // 复制原对象的所有属性 fruit: obj.fruit.filter(ele => elements.includes(ele.name)) // 覆盖fruit为过滤后的数组 })); console.log(results);
方案二:reduce 一步完成(性能更优)
如果处理的数组规模较大,用reduce可以减少一次遍历,性能更好:
const elements = ['apple']; const objects = [ { id: 1, fruit:[{"name": "apple" },{"name": "banana" }]}, { id: 2, fruit:[{"name": "apple" },{"name": "orange" }]}, { id: 3, fruit:[{"name": "orange" },{"name": "banana" }]}, { id: 4, fruit:[{"name": "orange" },{"name": "banana" }]} ]; const results = objects.reduce((acc, obj) => { // 先过滤当前对象的fruit数组 const filteredFruits = obj.fruit.filter(ele => elements.includes(ele.name)); // 如果过滤后有结果,就把新对象加入结果数组 if (filteredFruits.length > 0) { acc.push({ ...obj, fruit: filteredFruits }); } return acc; }, []); console.log(results);
关键细节说明
- 用
some替代内层filter做筛选判断:some只要找到第一个符合条件的元素就会停止遍历,比filter(遍历全部元素)更高效。 - 用扩展运算符
...obj复制原对象:避免直接修改原数组中的对象,保证数据不可变性。
内容的提问来源于stack exchange,提问作者vme
相关产品推荐
相关产品推荐

