You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript中使用Set()添加对象时仍出现重复值是什么原因?

问题描述

在JavaScript中使用Set()实现数据去重、获取唯一值时,返回结果始终存在重复条目。
控制台调试截图:
控制台调试截图
对应实现代码:

userStories.add({
   user_id: storie.user_id,
   avatar: storie.user.avatar,
});
根本原因

Set对重复值的判定遵循SameValueZero算法,和严格相等运算符===的逻辑几乎一致:

  • 原始类型(数字、字符串、布尔值等)会直接对比值是否相等
  • 对象、数组这类引用类型,只会对比值的内存引用地址,不会深度校验内部属性是否一致

你每次执行add()操作时传入的都是新创建的对象字面量,即使两个对象的user_id、avatar属性值完全相同,它们在内存中也是独立的不同引用,Set会将其判定为两个不重复的值,自然无法实现预期的去重效果。

可行解决方案
  • 方案1:改用Map按唯一标识去重(最推荐,性能最好)
    你的场景里user_id本身就是用户的唯一标识,用Map以user_id为键存储数据,相同键的内容会直接覆盖,天然实现按用户维度去重:
    // 初始化存储结构
    const userStories = new Map();
    
    // 遍历数据时执行添加操作
    userStories.set(storie.user_id, {
      user_id: storie.user_id,
      avatar: storie.user.avatar
    });
    
    // 最终需要数组结果时,直接取出所有值即可
    const uniqueUserList = [...userStories.values()];
    
  • 方案2:序列化后用Set去重(适合简单对象场景)
    如果一定要用Set,可以先把对象序列化为字符串存入Set,利用原始类型值的对比规则去重,使用时再反序列化回对象。注意该方法不适用于包含函数、循环引用、undefined值的复杂对象:
    const tempSet = new Set();
    
    // 添加时序列化
    tempSet.add(JSON.stringify({
      user_id: storie.user_id,
      avatar: storie.user.avatar
    }));
    
    // 最终结果反序列化为对象数组
    const uniqueUserList = [...tempSet].map(item => JSON.parse(item));
    
  • 方案3:数组方法按唯一字段过滤
    如果是对已有的数组做去重,可以直接用filter配合findIndex,按user_id字段过滤重复项:
    const uniqueUserList = storyList.filter((storie, index, arr) => {
      return arr.findIndex(item => item.user_id === storie.user_id) === index;
    });
    

内容的提问来源于stack exchange,提问作者Pedro Xavier

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 23:48:22