位运算不能安全通用地实现数组去重,因其仅操作二进制位、无法记忆已出现元素、不支持负数/小数/大整数,且误用如reduce异或会丢失数组结构;推荐使用Set法等真正去重方案。

JS 数组去重**不能直接用位运算(如 &、|、^)安全、通用地过滤纯数字数组**。位运算本身不提供“判重”或“集合去重”能力,它操作的是整数的二进制位,而非数组元素的唯一性逻辑。
为什么位运算不适合数组去重
位运算(如 a & b、a ^ b)作用对象是两个数值,结果仍是单个数值;它无法:
- 遍历并记忆已出现过的多个数字
- 区分重复项与首次出现项
- 保留原始顺序或生成新数组
- 处理负数、小数、大整数(超过 32 位有符号整数范围时,
>> 0或按位操作会出错)
有人误用的“位运算去重”其实是误解
例如下面这段常见误导代码:
const arr = [1, 2, 2, 3, 4, 4]; const unique = arr.reduce((a, b) => a ^ b); // ❌ 错!结果是 1^2^2^3^4^4 = 1^3 = 2(完全不是去重数组)
这实际计算的是异或累积值,不是去重——它把整个数组“压缩”成一个数,丢失全部结构和元素信息。
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
真正高效且适合纯数字数组的方案(非位运算,但更合理)
如果你追求性能和简洁,以下才是推荐做法:
-
Set 法(首选):
[new Set(arr)]——自动去重、保序、支持所有数字(含负数、小数、NaN),时间复杂度 O(n) -
Map 标记法(需兼容旧环境):
arr.filter((x, i) => !map.has(x) && map.set(x, 1))——精确控制,避免类型隐式转换 -
对象键名法(仅限安全整数):
arr.filter((x, i, a) => a.indexOf(x) === i)或用{}存键(但注意obj[0]和obj['0']相同,且obj[-1]、obj[1.5]会被转字符串,不推荐)
补充说明:位运算在去重中唯一可能的辅助角色
仅在极特殊场景下可间接参与,例如:
- 用
value >>> 0将浮点索引转为无符号整数(用于模拟数组下标,但非去重本身) - 用
flag |= (1 实现 **0–31 范围内整数的快速存在标记**(如 <code>[1,2,2,3]→ 用一个整数0b1110表示 1/2/3 已出现),但这要求数据严格满足:
✓ 全为 0–31 的非负整数
✓ 不关心顺序
✓ 只需判断“是否出现过”,不要求返回去重后数组
✗ 无法处理重复值以外的任何情况
这种技巧属于底层位图优化,不属于通用数组去重方法,日常开发中几乎不用。

















