javascript数组去重时,1和"1"默认不相等;用set或filter+indexof可严格区分类型,保留二者;json.stringify或tostring会误合并;若需逻辑合并,应先归一化再去重。

JavaScript 数组去重时,数字和数字字符串(如 1 和 "1")默认是**不相等**的,但若用某些方法(如 `Set` 或 `includes`)不做类型检查,容易误判为相同。关键在于明确你是否需要**严格区分类型**——即把 1 和 "1" 当作两个不同元素。
用 Set + 严格相等(推荐:保留类型差异)
`Set` 默认使用 SameValueZero 算法,它把 1 和 "1" 视为不同值(因为类型不同),所以直接用 `Set` 是最简单且符合预期的方式:
const arr = [1, "1", 2, "2", 1, "1"]; const unique = [...new Set(arr)]; console.log(unique); // [1, "1", 2, "2"]
✅ 完全保留原始类型,数字和数字字符串互不干扰。
用 filter + indexOf(注意隐式转换陷阱)
如果写成 arr.filter((item, i) => arr.indexOf(item) === i),它本身是严格比较,indexOf("1") 不会匹配数字 1,所以也安全:
-
[1, "1", 1].indexOf("1")→ 返回1(不是0) -
[1, "1", 1].indexOf(1)→ 返回0(不是1)
⚠️ 但要注意:如果数组里混有 0 和 false、"" 和 false 等,`indexOf` 仍严格比较,不会误判(这点比 `==` 可靠得多)。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
避免用 JSON.stringify 或 toString(会丢失类型区别)
以下写法会把数字和字符串“拉平”,导致错误去重:
// ❌ 错误:把 1 和 "1" 都转成 "1" arr.filter((item, i) => arr.map(JSON.stringify).indexOf(JSON.stringify(item)) === i); // 结果:["1", 2, "2"] —— 数字 1 被删掉了
类似地,用 String(item) 或 item + "" 做键也会合并不同类型。除非你**明确想要忽略类型**,否则不要这么做。
按需定制:想合并数字和数字字符串?
如果你的业务逻辑确实认为 "1" 和 1 是同一个值(比如用户输入后统一处理),可以先归一化再过滤:
- 转成数字再比较(注意
"abc"会变NaN) - 或统一转字符串(
String(item)),但要小心1和1.0是否算相同
例如只对纯数字字符串转 number:
const normalize = item => typeof item === 'string' && /^-?\d+$/.test(item) ? Number(item) : item; const normalized = arr.map(normalize); const uniqueByLogic = [...new Set(normalized)]; // [1, 2, "2"]
这样 "1" → 1,和已有数字 1 合并;而 "2" 保留(因原数组已有数字 2,所以去重后只剩一个 2)。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










