JavaScript中按指定键从对象数组获取唯一对象的高性能实现方法
按指定键对对象数组去重的高性能实现
传统「foreach遍历+判断元素是否存在于结果数组再追加」的方案,核心性能瓶颈是每次判断都要线性扫描已有结果数组,整体时间复杂度为O(n²),数据量越大时性能下降越明显。基于哈希结构的实现可以把整体复杂度降到O(n),是当前JS环境下的最优通用方案。
核心优化思路
利用JS内置Map、Set这类哈希结构的键查询、写入操作都是常数时间(O(1))的特性,遍历原数组过程中同步记录已经出现过的去重键,只保留第一次出现的同键对象,全程不需要嵌套循环扫描结果数组。
基于Map的实现示例
const array = [ {"name": "Joe", "age": 42}, {"name": "Donald", "age": 69}, {"name": "John", "age": 42}, ] const uniqueMap = new Map() // 单次遍历原数组 for (const item of array) { // 仅当当前元素的去重键(age)未被记录过时,才存入Map if (!uniqueMap.has(item.age)) { uniqueMap.set(item.age, item) } } // 将Map中存储的对象转成最终结果数组 const result = Array.from(uniqueMap.values)
方案灵活调整方式
- 如果需要保留同键值最后出现的对象,只需要调整判断逻辑:遍历过程中每次都用当前元素覆盖Map里对应键的值,不需要额外修改流程
- 如果去重键是字符串、数字这类基础类型,可以直接用
Set做键的存在性判断,写法更简洁:
const seenAges = new Set() const result = [] for (const item of array) { if (!seenAges.has(item.age)) { seenAges.add(item.age) result.push(item) } }
不同实现的性能对比
- 传统O(n²)方案:当数组长度达到10000条时,最坏情况需要执行近5000万次元素比较,大场景下容易出现主线程卡顿
- Map/Set优化方案:无论数组长度多大,都只需要一次遍历完成处理,相同数据量下性能比传统方案高1~2个数量级
- 这类优化属于典型的空间换时间:仅需要额外占用和已出现去重键数量等量的内存,在前端业务场景下这点内存开销完全可以忽略,远小于性能提升带来的收益
内容的提问来源于stack exchange,提问作者Jacob Hansen
相关产品推荐
相关产品推荐

