JavaScript对比两个数组过滤目标数组的优化实现方案
寻求优化解决方案
现有两个数组,需要筛选出其中一个数组内、属性值存在于另一个数组中的元素。
示例数据
data1 = [ { "c_id": 90, "c_name": "Test 1", }, { "c_id": 95, "c_name": "Test 2", }, { "c_id": 93, "c_name": "Test 3", } ] data2 = [ { "id": 92, "name": "Test 4", "rates": [] }, { "id": 90, "name": "Test 1", "rates": [] }, { "id": 95, "name": "Test 2", "rates": [] }, { "id": 93, "name": "Test 3", "rates": [] }, ]
需求:过滤data2,仅保留id字段值存在于data1的c_id字段中的元素。
原有代码的问题
你现在写的代码虽然能跑,但有几个明显的问题:
- 错用了
filter:filter的作用是返回符合条件的新数组,你这里把它当成普通遍历方法用,完全没用到它的返回值,属于不必要的方法调用 - 重复查询:每次匹配到对应元素时,你连续调用了两次
data2.find,同一个查找逻辑跑了两遍,做了无用功 - 性能差:两层嵌套循环的时间复杂度是O(n*m),两个数组长度越大,执行速度越慢
优化方案
推荐方案:用Set做预存,性能最优
先把data1里所有c_id提取出来存入Set,Set的has查找是O(1)时间复杂度,整体只需要遍历两次数组,总时间复杂度O(n+m),数据量越大优势越明显:
// 先把所有合法id存到Set里 const validCIds = new Set(data1.map(item => item.c_id)) // 直接过滤data2就行 const result = data2.filter(item => validCIds.has(item.id)) console.log(result)
如果你需要输出结果的顺序和data1里的c_id顺序保持一致,可以用Map预存data2的键值对:
const data2Map = new Map(data2.map(item => [item.id, item])) const result = data1.map(item => data2Map.get(item.c_id)).filter(Boolean) console.log(result)
小数据量简化写法
如果两个数组长度都很小(百条数据以内),也可以直接简化原有写法,不需要额外声明空数组、不需要重复find:
const result = data1.flatMap(item => data2.filter(i => i.id === item.c_id))
注意:这个写法本质还是两层嵌套遍历,数据量大的时候不推荐用。
内容的提问来源于stack exchange,提问作者Rich
相关产品推荐
相关产品推荐

