资讯动态

es-toolkit/fp 的 xorWith:在 pipe 管线中基于自定义相等函数计算对称差集

发布时间:2026/9/16 14:42:17 来源:尧图企业网站定制
es-toolkit/fp 的 xorWith在 pipe 管线中基于自定义相等函数计算对称差集【免费下载链接】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-toolkitxorWith是 es-toolkit 函数式编程入口es-toolkit/fp提供的数组操作符之一它接受第二数组与自定义相等函数返回一个等待数据的函数用于在pipe管线中计算两个数组的对称差集symmetric difference即只存在于其中一个数组、不同时存在于两个数组中的元素。读完本文你将掌握xorWith的调用签名、与原始es-toolkit/array版本的分工并能从 src/fp/array/xorWith.ts 与 src/array/xorWith.ts 的源码层面理解其并集减交集的实现原理与复杂度特征。一、为什么需要 FP 变体data-last 与 pipe 的组合官方文档明确给出了它的定位xorWith创建一个使用自定义相等函数返回对称差集的函数专用于与pipe搭配使用const result pipe(array, xorWith(secondArray, areItemsEqual));同时文档也强调了一个使用原则引用自 docs/fp/reference/xorWith.md在普通代码中优先使用原始 es-toolkit 的xorWith只有当你需要通过pipe组合变换时才使用这个fp变体。这一设计贯穿整个es-toolkit/fp模块。正如 docs/fp/intro.md 所述每个fp函数都以配置参数先行调用如map(fn)、take(2)返回一个等待数据输入的函数再由pipe从左到右、自上而下地依次喂入数据从而把嵌套调用改写成可读的流水线。xorWith也不例外secondArray和areItemsEqual属于配置真正参与变换的数据第一个数组由pipe在运行时提供。二、快速上手在 pipe 中计算对称差集xorWith根据areItemsEqual返回两个数组中未被匹配上的值。文档给出的标准示例import { pipe, xorWith } from es-toolkit/fp; pipe( [{ id: 1 }, { id: 2 }], xorWith([{ id: 2 }, { id: 3 }], (a, b) a.id b.id) ); // [{ id: 1 }, { id: 3 }]执行过程可以这样理解两个数组都包含{ id: 2 }按a.id b.id视为相等因此它属于交集被剔除{ id: 1 }只出现在第一个数组、{ id: 3 }只出现在第二个数组二者保留下来组成结果[{ id: 1 }, { id: 3 }]。该示例同时出现在 src/fp/array/xorWith.ts 的 JSDoc 中并由 src/fp/array/xorWith.spec.ts 的works in a pipe用例做了断言验证——pipe([{ id: 1 }, { id: 2 }], xorWith([{ id: 2 }, { id: 3 }], (a, b) a.id b.id))期望严格等于[{ id: 1 }, { id: 3 }]。三、参数与返回值详解根据 docs/fp/reference/xorWith.mdxorWith的完整签名如下Parameters参数类型说明secondArrayreadonly T[]与管线中传入数组进行比较的数组areItemsEqual(item: T, other: T) boolean决定两个值是否相等的函数相等返回true否则返回falseReturns返回值类型说明函数(array: readonly T[]) T[]一个将readonly T[]映射为按自定义相等规则计算的对称差集的函数对照 src/fp/array/xorWith.ts 的实现签名与文档完全一致export function xorWithT( secondArray: readonly T[], areItemsEqual: (item: T, other: T) boolean ): (array: readonly T[]) T[] { return function (array: readonly T[]): T[] { return xorWithToolkit(array, secondArray, areItemsEqual); }; }注意调用顺序的差异FP 变体把第二数组放在前面xorWith(secondArray, areItemsEqual)因为它是预置的配置而真正由pipe喂入的第一个数组在返回的函数内部才被接收并作为原始xorWith的arr1传入。四、底层实现FP 包装器如何复用核心算法es-toolkit/fp整体上复用es-toolkit的实现xorWith也是如此。FP 包装函数src/fp/array/xorWith.ts只是把参数顺序做了柯里化式的调整最终调用的是 src/array/xorWith.ts 中的核心实现export function xorWithT( arr1: readonly T[], arr2: readonly T[], areElementsEqual: (item1: T, item2: T) boolean ): T[] { const union unionWith(arr1, arr2, areElementsEqual); const intersection intersectionWith(arr1, arr2, areElementsEqual); return differenceWith(union, intersection, areElementsEqual); }这里采用了一个经典的集合恒等式对称差集 并集 − 交集。整个过程由三个同样位于 src/array 目录下的基础函数协作完成unionWith将两个数组合并后用uniqWith去重得到并集。内部实现是uniqWith(arr1.concat(arr2), areItemsEqual)。intersectionWith用firstArr.filter(...)配合secondArr.some(...)找出第一个数组中被第二个数组匹配上的元素得到交集。differenceWith用firstArr.filter(...)配合secondArr.every(item !areItemsEqual(...))剔除第二个数组中匹配到的元素得到差集。从源码结构可以推断复杂度特征intersectionWith与differenceWith内部都依赖some/every对另一数组做全量扫描因此整体是 O(n·m) 级别的两两比较——这正是自定义相等函数相比基于Set的按引用去重如xor所付出的代价换来的是对复杂对象与自定义相等语义的完全掌控。若追求极致性能且元素是原始值可优先考虑普通xor当元素是对象、或需要特殊比较规则时xorWith才是合适的选择。五、自定义相等函数不止于比较 idxorWith的价值在于areItemsEqual完全由调用方定义因此可以表达任意相等语义。原始版本文档 docs/reference/array/xorWith.md 提供了更多可迁移到 FP 变体中的用法import { pipe, xorWith } from es-toolkit/fp; // 1. 按对象 id 比较即使其他字段不同如 Bob 与 Bobby pipe( [ { id: 1, name: Alice }, { id: 2, name: Bob }, ], xorWith( [ { id: 2, name: Bobby }, { id: 3, name: Charlie }, ], (a, b) a.id b.id ) ); // [{ id: 1, name: Alice }, { id: 3, name: Charlie }] // 2. 大小写不敏感比较 pipe([Apple, Banana], xorWith([APPLE, Cherry], (a, b) a.toLowerCase() b.toLowerCase())); // [Banana, Cherry] // 3. 按绝对值比较 pipe([-1, -2, 3], xorWith([1, 2, -4], (a, b) Math.abs(a) Math.abs(b))); // [3, -4] // 4. 深度对象比较逐字段比较 pipe( [{ specs: { ram: 8, storage: 256 } }], xorWith([{ specs: { ram: 8, storage: 256 } }], (a, b) a.specs.ram b.specs.ram a.specs.storage b.specs.storage) ); // []这些示例展示了同一个核心能力只要areItemsEqual返回true即视为同一元素无论底层是字段投影、字符串归一化还是深度比较。边界情况也可从 src/array/xorWith.spec.ts 的测试中确认两数组无交集时返回全部元素xorWith([1, 2, 3], [4, 5, 6], ...) [1, 2, 3, 4, 5, 6]两数组完全相等时返回空数组xorWith([1, 2, 3], [1, 2, 3], ...) []任一数组为空时返回另一个数组的全部元素[]与[1, 2, 3]的两种情况均成立。六、在 pipe 管线中的位置xorWith 不是惰性函数pipe是es-toolkit/fp的入口其核心实现在 src/fp/pipe.ts它把传入的函数按是否具备lazy属性分组成连续片段——连续的惰性函数map、filter、take等会被融合成单次遍历、支持提前终止其余函数则逐个按顺序应用。从源码结构看xorWith返回的函数并未暴露lazy属性src/fp/array/xorWith.ts 中只有普通的闭包返回因此在pipe中它走的是普通非融合求值路径先由前序步骤产出完整数组再整体交给xorWith计算。这意味着在pipe中使用xorWith时无法享受惰性融合带来的提前终止优化但它依然是数据流中语义清晰的一环。一个典型的组合模式是先用filter、map等惰性操作符预处理数组再交给xorWith与参考数组做对称差比较xorWith之后仍可继续接其他变换整个管线保持自上而下的可读性。七、总结es-toolkit/fp的xorWith是配置先行、数据后置设计哲学的典型代表何时使用在pipe组合变换中需要计算两个数组的对称差集且相等判定需要自定义逻辑时何时不用普通直接调用场景请使用es-toolkit/array的xorWith参数顺序更直观xorWith(arr1, arr2, areItemsEqual)如何工作FP 包装器src/fp/array/xorWith.ts将参数柯里化底层核心src/array/xorWith.ts通过并集减交集unionWith→intersectionWith→differenceWith实现 O(n·m) 的自定义相等比较可验证性功能行为由 src/array/xorWith.spec.ts 与 src/fp/array/xorWith.spec.ts 两组测试用例保障。掌握这一模式后你可以在自己的管线中自由组合xorWith与其他fp操作符用一致、可读的方式处理找差异类的数据清洗与对比任务。【免费下载链接】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),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价