如何基于一个对象数组过滤另一个对象数组,保留dateTime不匹配元素
逻辑错误说明
- 每次循环都基于完整的原始arr执行过滤,没有继承上一轮的过滤结果,只会排除当前brr元素对应的dateTime,上一轮已经排除的内容会被重新加回来
- 每次过滤得到的数组被直接
push到newArr中,最终newArr会是二维数组,和预期的一维结构不符
修复方案
推荐性能更优的实现:先把brr中所有的dateTime存入Set做查询索引,再直接过滤arr即可,时间复杂度为O(n+m),远优于嵌套循环的O(n*m):
const arr = [ { dateTime: '2021-08-14 02:00:00', count: 1 }, { dateTime: '2021-08-15 04:00:00', count: 1 }, { dateTime: '2021-08-16 10:00:00', count: 1 }, { dateTime: '2021-08-16 19:00:00', count: 1 }, { dateTime: '2021-08-17 05:00:00', count: 1 } ]; const brr = [ { dateTime: '2021-08-16 19:00:00', count: 1 }, { dateTime: '2021-08-17 05:00:00', count: 1 } ]; // 提取brr所有dateTime存入Set,用于快速查询 const brrDateTimeSet = new Set(brr.map(item => item.dateTime)); // 过滤arr,只保留dateTime不在Set中的项 const newArr = arr.filter(item => !brrDateTimeSet.has(item.dateTime)); console.log(newArr);
执行后输出结果为:
[ { dateTime: '2021-08-14 02:00:00', count: 1 }, { dateTime: '2021-08-15 04:00:00', count: 1 }, { dateTime: '2021-08-16 10:00:00', count: 1 } ]
如果要基于你原来的循环逻辑修改,可以参考如下写法(性能低于Set方案,不推荐长数组场景使用):
// 先复制原始arr作为过滤起点 let newArr = [...arr]; for( let item of brr ) { // 基于上一轮过滤后的结果继续过滤,而不是原始arr newArr = newArr.filter( el => el.dateTime !== item.dateTime ); }; console.log(newArr);
内容的提问来源于stack exchange,提问作者s.khan
相关产品推荐
相关产品推荐

