如何比较并过滤具有一对多关系的两个JavaScript对象?
过滤与pathways存在映射关系的Clusters
问题描述
给定两个JavaScript对象:
const pathways = [{area: 1, clusterId: 1},{area: 2, clusterId: 4}]; const clusters = [{id:1,name:'london'},{id:2, name: 'paris'},{id:3, name:'rome'},{id:4, name: 'brussel'}];
需要过滤clusters,仅保留那些id在pathways的clusterId中存在的项,预期输出:
[{id:1,name:'london'}, {id:4, name: 'brussel'}]
尝试了以下代码,但运行报错Error: Cannot read properties of undefined (reading 'clusterId'):
let pathways = [{id: 1, clusterId: 1},{id: 2, clusterId: 4}]; let clusters = [{id:1,name:'london'},{id:2, name: 'paris'},{id:3, name:'rome'},{id:4, name: 'brussel'}]; clusters = clusters.filter((cluster, i) => { if (cluster.id === pathways[i].clusterId) { return clusters; } }); console.log(clusters);
错误原因
- 索引不匹配:
filter的第二个参数i是clusters的索引,而pathways的长度(2)小于clusters的长度(4)。当i=2和i=3时,pathways[i]为undefined,自然无法读取clusterId属性,导致报错。 - 返回值错误:
filter的回调函数需要返回布尔值(true保留当前项,false过滤掉),但你返回的是整个clusters数组,逻辑完全错误。
正确解法
方法1:使用Array.some()直接匹配
遍历clusters时,检查当前cluster.id是否存在于pathways的clusterId列表中:
const pathways = [{area: 1, clusterId: 1},{area: 2, clusterId: 4}]; const clusters = [{id:1,name:'london'},{id:2, name: 'paris'},{id:3, name:'rome'},{id:4, name: 'brussel'}]; const filteredClusters = clusters.filter(cluster => { return pathways.some(pathway => pathway.clusterId === cluster.id); }); console.log(filteredClusters); // 输出:[{id:1,name:'london'}, {id:4, name: 'brussel'}]
方法2:用Set优化查找效率(适合大数据量)
先把pathways中的clusterId提取到Set中,利用Set.has()的O(1)查找性能,避免每次都遍历pathways:
const pathways = [{area: 1, clusterId: 1},{area: 2, clusterId: 4}]; const clusters = [{id:1,name:'london'},{id:2, name: 'paris'},{id:3, name:'rome'},{id:4, name: 'brussel'}]; const validClusterIds = new Set(pathways.map(p => p.clusterId)); const filteredClusters = clusters.filter(cluster => validClusterIds.has(cluster.id)); console.log(filteredClusters); // 输出:[{id:1,name:'london'}, {id:4, name: 'brussel'}]
内容的提问来源于stack exchange,提问作者karthik power
相关产品推荐
相关产品推荐

