数组去重需按业务语义统一类型:数字语义用 Array.from(new Set(arr.map(Number))) 并过滤 NaN;字符串语义用 Array.from(new Set(arr.map(String)));精细控制则用 Map 自定义 key。

JS 数组去重时,数字和字符串混合(比如 [1, "1", 2, "2", "3"])最容易掉进隐式转换的坑——Set 或 filter + indexOf 默认按严格相等(===)判断,所以 1 和 "1" 被视为两个不同值,不会去重。但业务上常要求“语义相同即算重复”,这时必须主动干预类型,不能依赖默认行为。
统一转为同一种类型再用 Set
这是最直接、可控的做法。先明确业务规则:是按数字语义去重?还是按字符串语义?然后批量转换。
- 按数字去重(推荐多数场景):
Array.from(new Set(arr.map(Number))),注意Number("abc")得NaN,需额外过滤 - 按字符串去重:
Array.from(new Set(arr.map(String))),String(0)→"0",String(false)→"false",要确认是否符合预期 - 更稳妥的数字处理:
arr.map(x => { const n = Number(x); return isNaN(n) ? x : n; }),保留无法转数字的原始值
用 Map 手动实现语义级去重
当需要精细控制“什么算重复”时(例如 "01" 和 1 不算重复,但 "1" 和 1 算),Map 是比 Set 更灵活的选择。
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
- 键名用标准化后的字符串(如
JSON.stringify({ type: typeof x, value: x })),确保类型+值双重唯一 - 或自定义 key 生成逻辑:
const getKey = x => typeof x === 'number' ? `num:${x}` : `str:${x}`,再用 Map 去重 - 优势:完全绕过 JS 内置比较机制,避免
==或===的任何隐式行为
避免踩坑的关键检查点
不是做完转换就万事大吉,这几个细节常被忽略:
-
空格和边界字符:用户输入的
" 1 "转数字是1,但转字符串是" 1 ",建议提前.trim() -
特殊值处理:
null、undefined、NaN经Number()后都变成0或NaN,若需区分,得单独分支判断 -
布尔值陷阱:
Number(true)是1,Number(false)是0,如果数组含布尔值,要确认是否允许与数字合并 -
性能提醒:对超大数组,
map+Set是 O(n),安全;但用includes或双循环是 O(n²),慎用
用 TypeScript 提前拦截类型混乱
长期来看,靠运行时转换是补救,类型系统才是根治。在接口层或 store 定义中明确字段类型:
- 后端返回 ID 字段,前端用
id: number接口定义,让 Axios 或 SWR 自动做Number()转换 - 组件 props 标注
userId?: number,配合 ESLint 规则no-implicit-coercion禁止+x等简写 - 这样从数据源头就保证类型一致,去重时直接用
new Set(arr)就足够可靠

















