JavaScript比较嵌套对象数组,返回sos首项street未匹配的arr2对象
JavaScript嵌套对象数组匹配实现方案
问题背景
现有两个嵌套结构的对象数组arr1和arr2,结构如下:
let arr1 =[{ id: 1, rideS: [ { id: 12, station: { id: 23, street: "ABC" } } ] }, { id: 2, rideS: [ { id: 13, station: { id: 24, street: "MMM" } } ] } ] let arr2 = [ { id: 1, so: { id: 33, sos: [{ id: 44, station: { id: 55, street: "ABC" } }, { id: 74, station: { id: 11, street: "DDD" } } ] } }, { id: 2, so: { id: 34, sos: [{ id: 45, station: { id: 56, street: "RRR" } }, { id: 51, station: { id: 66, street: "ZZZ" } } ] } }, { id: 3, so: { id: 35, sos: [{ id: 46, station: { id: 57, street: "MMM" } }, { id: 75, station: { id: 66, street: "VVV" } } ] } } ]
匹配规则
- 取
arr2每个元素中so.sos数组第一个对象的station.street属性值 - 将上述值与
arr1所有元素rideS数组内对象的station.street属性值做匹配 - 最终返回
arr2中street值未命中匹配的对象,预期结果如下:
let result = [ { id: 2, so: { id: 34, sos: [{ id: 45, station: { id: 56, street: "RRR" } }, { id: 51, station: { id: 66, street: "ZZZ" } } ] } } ]
原有代码错误原因
- 第一版代码遍历了
arr2中全部的sos数组元素,没有按照要求只取第一个元素做比对,只要sos中有任意一个street未匹配就会被返回,不符合需求 - 第二版代码错误地对
sos[0](对象类型)调用数组方法some,直接触发语法错误无法运行
正确实现方案
基础实现(逻辑直观)
直接按照规则逐层取值判断即可:
const result = arr2.filter(item => { // 取当前arr2元素的sos第一个元素的street const targetStreet = item.so.sos[0].station.street; // 检查arr1中是否存在该street const isMatched = arr1.some(a1 => a1.rideS.some(ride => ride.station.street === targetStreet) ); // 保留未命中的元素 return !isMatched; });
优化实现(性能更优,适合大数据量场景)
先把arr1中所有的street提取为Set集合,后续匹配直接O(1)判断,避免重复遍历arr1:
// 预提取arr1所有有效street存入集合 const streetSet = new Set(); arr1.forEach(a1 => { a1.rideS.forEach(ride => streetSet.add(ride.station.street)); }); // 过滤arr2 const result = arr2.filter(item => { const targetStreet = item.so.sos[0].station.street; return !streetSet.has(targetStreet); });
内容的提问来源于stack exchange,提问作者Stefan Simić
相关产品推荐
相关产品推荐

