es-toolkit 数组对称差集函数 xor 使用指南:从入门到源码解析
es-toolkit 数组对称差集函数 xor 使用指南从入门到源码解析【免费下载链接】es-toolkitA modern JavaScript utility library thats 2-3 times faster and up to 97% smaller, a major upgrade to lodash.项目地址: https://gitcode.com/GitHub_Trending/es/es-toolkit对称差集symmetric difference是集合运算中的经典概念取两个集合中只出现在其中一方、而不会同时出现在两边的元素。es-toolkit 在数组工具集中提供了xor函数来实现这一运算它以极简的 API 完成「去重 取对称差」两项任务。本文将以官方参考文档docs/ja/reference/array/xor.md为核心完整介绍xor的用法、参数与返回值并深入 src/array/xor.ts 的源码剖析其内部调用链与边界行为帮助你在实际项目中准确、高效地使用它。xor 是什么一次搞懂对称差集xor的名字源自逻辑运算「异或」exclusive OR对于两个输入只有当元素「只属于其中一边」时才被保留。用集合论的语言描述就是两个数组的对称差集对称差集 (arr1 ∪ arr2) − (arr1 ∩ arr2)即两个数组中任一一边存在、但不同时存在于两边的元素组成的新数组。官方的类型签名如下const result xor(arr1, arr2);该函数定义在 src/array/xor.ts并通过 src/array/index.ts 对外导出可从es-toolkit/array子路径引入。基本用法数值与字符串数组在需要求两个数组对称差集的场景下直接调用xor(arr1, arr2)即可。它返回一个全新的数组由只出现在其中一个数组中的元素构成且保持元素在数组中首次出现的顺序。import { xor } from es-toolkit/array; // 数值数组的对称差集 xor([1, 2, 3, 4], [3, 4, 5, 6]); // 返回: [1, 2, 5, 6] // 字符串数组的对称差集 xor([a, b], [b, c]); // 返回: [a, c]第一组示例中3和4同时出现在两个数组里属于交集被剔除1、2只属于第一个数组5、6只属于第二个数组因此结果保留[1, 2, 5, 6]。第二组字符串示例同理得到[a, c]。重复元素的自动去重与集合运算保持一致xor会自动去除重复元素。即使输入数组中某个元素出现多次只要它只属于其中一边最终结果中也只会保留一次import { xor } from es-toolkit/array; xor([1, 2, 2, 3], [3, 4, 4, 5]); // 返回: [1, 2, 4, 5]这里第一个数组中的2出现两次第二个数组中的4出现两次但结果中各自只保留一个。这一行为与 lodash 的xor语义一致也与数学上「集合不包含重复元素」的定义吻合。参数与返回值详解官方文档给出的参数定义如下参数类型说明arr1readonly T[]参与比较的第一个数组arr2readonly T[]参与比较的第二个数组返回值T[]—— 表示两个数组对称差集的新数组。值得注意的是参数类型被声明为readonly T[]这意味着你可以放心传入通过as const或ReadonlyArray定义的只读数组xor不会修改任何输入而是始终返回一个全新的数组。由于它内部不会对输入进行原地修改配合函数式编程风格使用也非常安全。源码解析一行代码背后的调用链xor的实现极其精简整个函数体只有一行// src/array/xor.ts import { difference } from ./difference.ts; import { intersection } from ./intersection.ts; import { union } from ./union.ts; export function xorT(arr1: readonly T[], arr2: readonly T[]): T[] { return difference(union(arr1, arr2), intersection(arr1, arr2)); }它复用了库内三个基础数组函数将对称差集拆解为「并集减去交集」的复合运算union(arr1, arr2)—— 先求并集。查看 src/array/union.ts其实现为uniq(arr1.concat(arr2))即先拼接两个数组再通过 src/array/uniq.ts 中的[...new Set(arr)]完成去重。这一步保证了「重复元素自动删除」的行为。intersection(arr1, arr2)—— 再求交集。查看 src/array/intersection.ts实现为将第二个数组转为Set后用firstArr.filter(item secondSet.has(item))筛出两边共有的元素。difference(union, intersection)—— 最后用并集减去交集。查看 src/array/difference.ts同样是先构建Set再过滤firstArr.filter(item !secondSet.has(item))。从源码结构看xor的复合实现充分利用了Set的哈希查找特性difference与intersection内部都是 O(n) 量级的过滤操作整体性能表现良好。三个基础函数各司其职也让xor的语义清晰可读并集保证不重不漏交集负责剔除共同元素差集完成最终筛选。边界情况验证来自测试用例的证据src/array/xor.spec.ts 中的测试用例完整覆盖了各类边界场景可以作为实际使用时的行为参考// 两个数组完全没有交集 → 返回两个数组的所有元素去重后 xor([1, 2, 3], [4, 5, 6]); // [1, 2, 3, 4, 5, 6] // 两个数组完全相同 → 对称差集为空 xor([1, 2, 3], [1, 2, 3]); // [] // 第一个数组为空 → 返回第二个数组 xor([], [1, 2, 3]); // [1, 2, 3] // 第二个数组为空 → 返回第一个数组 xor([1, 2, 3], []); // [1, 2, 3]这些用例揭示了几条实用结论完全不相交的两个数组xor退化为「并集去重」返回全部元素完全相同的两个数组xor返回空数组符合异或的语义两边都有则抵消空数组参与运算时xor等价于对另一数组执行去重。进阶xorBy 与 xorWith当元素是对象、或者需要按自定义规则比较时xor的兄弟函数xorBy与xorWith可以派上用场。它们位于兼容层compat目录下语义对齐 lodashxorBysrc/compat/array/xorBy.ts接受一个iteratee迭代函数先对每个元素生成比较依据再计算对称差集。例如按属性字符串或Math.floor等函数作为键xorBy([2.1, 1.2], [4.3, 2.4], Math.floor); // [1.2, 4.3] xorBy([{ x: 1 }], [{ x: 2 }, { x: 1 }], x); // [{ x: 2 }]xorWithsrc/compat/array/xorWith.ts接受一个comparator比较器用于自定义元素间的相等判断适合深度比较对象const objects [{ x: 1, y: 2 }, { x: 2, y: 1 }]; const others [{ x: 1, y: 1 }, { x: 1, y: 2 }]; xorWith(objects, others, isEqual); // [{ x: 2, y: 1 }, { x: 1, y: 1 }]另外src/compat/array/xor.ts 还提供了 lodash 风格的多数组版本xor(...arrays)支持传入两个以上数组通过计数每个元素在多少个数组中「只出现一次」来判断是否保留。如果你的代码正在从 lodash 迁移可以直接使用 compat 入口的对应函数两者行为保持一致。总结什么时候用 xorxor适用于一切「找出两边不一致元素」的场景例如对比两份配置、权限清单找出只属于其中一方的差异项数据同步时定位只在单侧存在的记录集合运算中替代手写filterincludes的组合逻辑。它接受只读数组、返回新数组、自动去重、不修改输入配合xorBy/xorWith可以覆盖从原始值到复杂对象的全部比较需求。无论你是 es-toolkit 的新用户还是从 lodash 迁移的老手xor都是一个值得优先掌握的数组工具。【免费下载链接】es-toolkitA modern JavaScript utility library thats 2-3 times faster and up to 97% smaller, a major upgrade to lodash.项目地址: https://gitcode.com/GitHub_Trending/es/es-toolkit创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考