对象数组如何去重

实现对象数组的去重功能,支持多种去重策略和自定义比较规则

问题

在实际开发中,我们经常需要对对象数组进行去重操作。与基本类型数组不同,对象数组的去重需要根据对象的某个或某些属性来判断是否重复。本文将介绍几种常见的对象数组去重方法。

解答

方法一:根据指定属性去重(使用 Map)

/**
 * 根据指定属性对对象数组去重
 * @param {Array} arr - 需要去重的对象数组
 * @param {String} key - 用于判断重复的属性名
 * @returns {Array} 去重后的数组
 */
function uniqueByKey(arr, key) {
  const map = new Map();
  return arr.filter(item => {
    const keyValue = item[key];
    if (!map.has(keyValue)) {
      map.set(keyValue, true);
      return true;
    }
    return false;
  });
}

方法二:根据多个属性去重

/**
 * 根据多个属性对对象数组去重
 * @param {Array} arr - 需要去重的对象数组
 * @param {Array} keys - 用于判断重复的属性名数组
 * @returns {Array} 去重后的数组
 */
function uniqueByKeys(arr, keys) {
  const map = new Map();
  return arr.filter(item => {
    // 将多个属性值组合成唯一标识
    const uniqueKey = keys.map(key => item[key]).join('|');
    if (!map.has(uniqueKey)) {
      map.set(uniqueKey, true);
      return true;
    }
    return false;
  });
}

方法三:使用 reduce 实现

/**
 * 使用 reduce 根据指定属性去重
 * @param {Array} arr - 需要去重的对象数组
 * @param {String} key - 用于判断重复的属性名
 * @returns {Array} 去重后的数组
 */
function uniqueByReduce(arr, key) {
  const map = new Map();
  return arr.reduce((acc, item) => {
    if (!map.has(item[key])) {
      map.set(item[key], true);
      acc.push(item);
    }
    return acc;
  }, []);
}

方法四:自定义比较函数

/**
 * 使用自定义比较函数去重
 * @param {Array} arr - 需要去重的对象数组
 * @param {Function} compareFn - 自定义比较函数,返回唯一标识
 * @returns {Array} 去重后的数组
 */
function uniqueByComparator(arr, compareFn) {
  const map = new Map();
  return arr.filter(item => {
    const key = compareFn(item);
    if (!map.has(key)) {
      map.set(key, true);
      return true;
    }
    return false;
  });
}

方法五:JSON 序列化(完全相同的对象)

/**
 * 通过 JSON 序列化去重(适用于完全相同的对象)
 * @param {Array} arr - 需要去重的对象数组
 * @returns {Array} 去重后的数组
 */
function uniqueByJSON(arr) {
  const map = new Map();
  return arr.filter(item => {
    const key = JSON.stringify(item);
    if (!map.has(key)) {
      map.set(key, true);
      return true;
    }
    return false;
  });
}

使用示例

// 示例数据
const users = [
  { id: 1, name: '张三', age: 25 },
  { id: 2, name: '李四', age: 30 },
  { id: 1, name: '张三', age: 25 },
  { id: 3, name: '王五', age: 25 },
  { id: 2, name: '李四', age: 35 }
];

// 示例1:根据 id 去重
console.log(uniqueByKey(users, 'id'));
// 输出: [
//   { id: 1, name: '张三', age: 25 },
//   { id: 2, name: '李四', age: 30 },
//   { id: 3, name: '王五', age: 25 }
// ]

// 示例2:根据多个属性去重(id 和 name)
console.log(uniqueByKeys(users, ['id', 'name']));
// 输出: [
//   { id: 1, name: '张三', age: 25 },
//   { id: 2, name: '李四', age: 30 },
//   { id: 3, name: '王五', age: 25 }
// ]

// 示例3:使用自定义比较函数(根据 name 和 age 组合)
console.log(uniqueByComparator(users, item => `${item.name}-${item.age}`));
// 输出: [
//   { id: 1, name: '张三', age: 25 },
//   { id: 2, name: '李四', age: 30 },
//   { id: 3, name: '王五', age: 25 },
//   { id: 2