【JS】---数组/对象数组 去重方法总结

115 阅读2分钟

1️⃣数组去重

const arr = [1, 2, 2, "a", "b", "a"];
// 目标输出:[1, 2, "a", "b"]

解法 1:使用 Set(最推荐、简洁)

const result = [...new Set(arr)];
console.log(result); // [1, 2, "a", "b"]

解法 2:使用 filter + indexOf

const result = arr.filter((item, index) => {
  return arr.indexOf(item) === index;
});
console.log(result); // [1, 2, "a", "b"]

indexOf(item) 会返回首次出现的位置,只有第一次才满足 index === indexOf(item)


解法 3:使用 filter + Object 作为哈希表

const seen = {};
const result = arr.filter(item => {
  if (seen[item]) return false;
  seen[item] = true;
  return true;
});
console.log(result); // [1, 2, "a", "b"]

注意:seen[item] 会将 1"1" 混为一类,不适合不同类型混用时的精确去重


解法 4:手动去重(支持复杂对象)

function deduplicate(arr) {
  const res = [];
  for (let i = 0; i < arr.length; i++) {
    if (!res.includes(arr[i])) {
      res.push(arr[i]);
    }
  }
  return res;
}
console.log(deduplicate(arr)); // [1, 2, "a", "b"]

📝总结建议:

方法是否推荐说明
Set✅ 强烈推荐最简洁高效
filter+indexOf老写法,兼容性好
Map/Object不适合数组元素为不同类型(如 1 和 "1")
includes手动最通用(适合学习原理)

2️⃣【进阶】对象数组去重(按 id)只保留每个 id 最先出现的一项。

给定一个对象数组,可能存在多个对象具有相同的 id,请你去除重复的对象,只保留每个 id 最先出现的一项。

const users = [
  { id: 1, name: "Alice" },
  { id: 2, name: "Bob" },
  { id: 1, name: "Alice Duplicate" },
  { id: 3, name: "Charlie" },
  { id: 2, name: "Bob Again" }
];

// 预期结果:
[
  { id: 1, name: "Alice" },
  { id: 2, name: "Bob" },
  { id: 3, name: "Charlie" }
]

方式一:使用 Map + filter 去重(最推荐)

const seen = new Map();
const result = users.filter(user => {
  if (!seen.has(user.id)) {
    seen.set(user.id, true);
    return true;
  }
  return false;
});
console.log(result);

方式二:使用 Set 配合 filter

const seen = new Set();
const result = users.filter(user => {
  if (seen.has(user.id)) return false;
  seen.add(user.id);
  return true;
});

方式三:使用 reduce + some 实现

const result = users.reduce((acc, curr) => {
  if (!acc.some(user => user.id === curr.id)) {
    acc.push(curr);
  }
  return acc;
}, []);

3️⃣【进阶2】对象数组按 id 去重,保留最后一个

目标数据:

const users = [
  { id: 1, name: "Alice" },
  { id: 2, name: "Bob" },
  { id: 1, name: "Alice Duplicate" },
  { id: 3, name: "Charlie" },
  { id: 2, name: "Bob Again" }
];

预期输出(保留最后一个 id 的对象):

[
  { id: 1, name: "Alice Duplicate" },
  { id: 3, name: "Charlie" },
  { id: 2, name: "Bob Again" }
]

解法 1:使用 Map(先从后往前处理)

const seen = new Map();
const result = [];

for (let i = users.length - 1; i >= 0; i--) {
  const user = users[i];
  if (!seen.has(user.id)) {
    seen.set(user.id, true);
    result.unshift(user); // 保证顺序
  }
}
console.log(result);

解法 2:使用 reduceRight + some

const result = users.reduceRight((acc, curr) => {
  if (!acc.some(user => user.id === curr.id)) {
    acc.unshift(curr); // 保证顺序
  }
  return acc;
}, []);

解法 3:先建哈希表,再映射输出(最快但无原始顺序)

const map = new Map();
users.forEach(user => {
  map.set(user.id, user); // 重复的会覆盖,最终保留最后一个
});
const result = Array.from(map.values());

✅ 这种方法最快,但原数组顺序可能被打乱