JS对象数组去重的多种实现方案与对比

作者:半夏

时间:2026-10-31

浏览:395

本文总结了JavaScript中实现对象数组去重的多种技术方案。从ES5的循环过滤到ES6的Set与Map应用,再到结合JSON.stringify的简单处理及Lodash库的便捷函数。此外还探讨了WeakMap、WeakRef等高级特性在内存管理与复杂场景下的适用性,帮助开发者根据实际需求选择最优解。

文章目录

ES5 方式

在 ES5 环境中,可以通过 for 遍历数组并结合数组过滤方法来完成对象数组的去重操作。

function uniqueArrayByProperty(array, property) {
  var seen = {};
  return array.filter(function(item) {
    var val = item[property];
    return seen.hasOwnProperty(val) ? false : (seen[val] = true);
  });
}

var arr = [
  { id: 1, name: 'Alice' },
  { id: 2, name: 'Bob' },
  { id: 1, name: 'Alice' }, // 重复
  { id: 3, name: 'Charlie' }
];

var uniqueArr = uniqueArrayByProperty(arr, 'id');
console.log(uniqueArr);
// 输出:[ { id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }, { id: 3, name: 'Charlie' } ]

ES6 及之后的方式

随着 ES6 标准的引入,处理数组和对象拥有了更多简洁高效的语法特性。

使用 Set 和 JSON.stringify / JSON.parse

该方案适用于结构简单的对象,但需留意 JSON.stringify 在序列化过程中会丢弃原型链上的属性,且若对象包含循环引用则会引发错误。

function uniqueArrayByPropertyES6(array, property) {
  const seen = new Set();
  return array.filter(item => {
    const val = JSON.stringify(item[property]);
    return seen.has(val) ? false : seen.add(val);
  });
}

var uniqueArrES6 = uniqueArrayByPropertyES6(arr, 'id');
console.log(uniqueArrES6);

使用 Map

针对更为复杂的对象去重场景,可以利用 Map 来记录已处理过的对象实例。

function uniqueArrayByPropertyWithMap(array, property) {
  const map = new Map();
  return array.filter(item => {
    const val = item[property];
    if (!map.has(val)) {
      map.set(val, true);
      return true;
    }
    return false;
  });
}

var uniqueArrWithMap = uniqueArrayByPropertyWithMap(arr, 'id');
console.log(uniqueArrWithMap);

使用 Map 结合自定义比较逻辑

当对象包含多个属性且需基于特定规则判断重复时,此方法允许通过自定义逻辑进行去重。

function uniqueArrayByProperties(array, properties) {
  const seen = new Map();
  return array.filter(item => {
    const key = properties.map(prop => item[prop]).join('|');
    if (!seen.has(key)) {
      seen.set(key, true);
      return true;
    }
    return false;
  });
}

const arr = [
  { id: 1, name: 'Alice' },
  { id: 2, name: 'Bob' },
  { id: 1, name: 'Alice' }, // 重复
  { id: 3, name: 'Charlie' }
];

const uniqueArr = uniqueArrayByProperties(arr, ['id', 'name']);
console.log(uniqueArr);
// 输出:[ { id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }, { id: 3, name: 'Charlie' } ]

使用 Lodash 库

借助 Lodash 库提供的 _.uniqBy 函数,可以非常便捷地实现去重功能。

const _ = require('lodash');

const uniqueArr = _.uniqBy(arr, 'id');
console.log(uniqueArr);
// 输出:[ { id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }, { id: 3, name: 'Charlie' } ]

使用 WeakMap

WeakMap 可用于存储对象引用,其优势在于不会阻碍相关对象被垃圾回收机制回收。尽管 WeakMap 要求键必须为对象,但它仍可用于追踪已处理过的对象。

function uniqueArrayByPropertyWithWeakMap(array, property) {
  const seen = new WeakMap();
  return array.filter(item => {
    const val = item[property];
    if (!seen.has(val)) {
      seen.set(val, true);
      return true;
    }
    return false;
  });
}

const uniqueArrWithWeakMap = uniqueArrayByPropertyWithWeakMap(arr, 'id');
console.log(uniqueArrWithWeakMap);
// 输出:[ { id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }, { id: 3, name: 'Charlie' } ]

使用 Set 和 WeakRef (实验性)

在较新的 JavaScript 版本中,WeakRef 可用于存储对象的弱引用,从而辅助对象去重。需要注意的是,WeakRef 目前属于实验性功能,未来版本中其行为可能发生变化。

const { WeakRef } = require('weakref'); // 假设这是一个支持 WeakRef 的环境

function uniqueArrayByPropertyWithWeakRef(array, property) {
  const seen = new Set();
  return array.filter(item => {
    const ref = new WeakRef(item[property]);
    if (!seen.has(ref)) {
      seen.add(ref);
      return true;
    }
    return false;
  });
}

const uniqueArrWithWeakRef = uniqueArrayByPropertyWithWeakRef(arr, 'id');
console.log(uniqueArrWithWeakRef);
// 输出:[ { id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }, { id: 3, name: 'Charlie' } ]

使用 Set 结合 JSON.stringify

对于简单对象,可通过 JSON.stringify 生成字符串表示,进而利用 Set 完成去重处理。

function uniqueArrayByPropertyWithSet(array, property) {
  const seen = new Set();
  return array.filter(item => {
    const val = JSON.stringify(item[property]);
    return seen.has(val) ? false : seen.add(val);
  });
}

const uniqueArrWithSet = uniqueArrayByPropertyWithSet(arr, 'id');
console.log(uniqueArrWithSet);
// 输出:[ { id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }, { id: 3, name: 'Charlie' } ]

总结

上述内容列举了实现 JavaScript 对象数组去重的多种路径(此类需求在项目中十分常见)。具体方法的选择应基于实际需求和运行环境。针对简单对象,采用 Set 配合 JSON.stringify 往往是最简方案;而面对复杂情况,Map 或 WeakMap 则更为适宜。若引入第三方库,Lodash 的 _.uniqBy 提供了便捷支持。对于如 WeakRef 等实验性功能,则需充分考量兼容性与稳定性。

以上就是JS对象去重的多种方式小结的详细内容,更多关于JS对象去重的资料请关注本站其它相关文章!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章