es-toolkit/compat 的 remove 函数详解:Lodash 兼容的多形态谓词数组删除 📅 发布时间:2026/9/16 16:47:14 👁 浏览次数: es-toolkit/compat 的 remove 函数详解Lodash 兼容的多形态谓词数组删除【免费下载链接】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导读本文基于 docs/ja/compat/reference/array/remove.md 展开深入解析es-toolkit兼容层es-toolkit/compat中remove函数的设计与用法。该函数从数组中原地删除满足条件的元素并返回被删元素集合与 Lodash 的_.remove行为保持一致。读完本文你将掌握remove支持的四种谓词形态函数、部分对象、属性-值对、属性名、其底层实现原理、与主库es-toolkit/array版本remove的性能差异以及稀疏数组等边界行为。概览与函数签名remove会遍历数组将满足条件的元素从原数组中删除并以一个新数组的形式返回所有被删除的元素。需要特别留意的是原数组会被直接修改in-place这与 Lodash 的语义一致。const removedElements remove(array, predicate);在es-toolkit/compat兼容层中其完整签名如下见 src/compat/array/remove.tsexport function removeT( arr: ArrayLikeT, shouldRemoveElement: | ((value: T, index: number, arr: ArrayLikeT) boolean) // 函数谓词 | PartialT // 部分对象匹配 | [keyof T, unknown] // 属性-值对 | keyof T // 属性名 | undefined // 缺省等价于 identity ): T[];参数参数类型说明arrayArrayLikeT要修改的数组支持类数组对象predicate可选((value, index, array) boolean) \| PartialT \| [keyof T, unknown] \| keyof T对每个元素执行的判定条件缺省时为identity恒等函数返回值T[]由所有被删除元素组成的新数组。四种谓词形态与实战用法兼容层remove的核心价值在于它通过 src/compat/util/iteratee.ts 将任意形态的谓词统一转换为判定函数从而完整覆盖 Lodash 的_.remove调用习惯。以下逐一说明代码示例均来自原文档。1. 函数谓词(value, index, array) boolean最通用的形式判定函数会依次收到当前元素、索引和原数组的副本三个参数import { remove } from es-toolkit/compat; // 函数を使用した条件で削除用函数条件删除 const numbers [1, 2, 3, 4, 5]; const evens remove(numbers, n n % 2 0); console.log(numbers); // [1, 3, 5]原数组已被修改 console.log(evens); // [2, 4]被删除的元素2. 部分对象匹配{ key: value }传入一个部分对象凡是与对象中列出的属性完全一致的元素都会被删除// 部分オブジェクトのマッチングで削除按部分对象匹配删除 const objects [{ a: 1 }, { a: 2 }, { a: 3 }]; const removed remove(objects, { a: 1 }); console.log(objects); // [{ a: 2 }, { a: 3 }] console.log(removed); // [{ a: 1 }]3. 属性-值对[key, value]传入一个长度为 2 的数组第一个元素为属性名第二个为期望值// プロパティ-値ペアで削除按属性-值对删除 const items [{ name: apple }, { name: banana }, { name: cherry }]; const cherries remove(items, [name, cherry]); console.log(items); // [{ name: apple }, { name: banana }] console.log(cherries); // [{ name: cherry }]4. 属性名propName传入一个属性名凡是该属性为真值truthy的元素都会被删除// プロパティ名で真値を確認按属性名判定真值 remove(users, isDeleted);汇总示例四种形态可在同一种业务场景中混用原文档给出了统一的演示import { remove } from es-toolkit/compat; // 函数条件 remove(users, user user.active false); // 部分对象匹配 remove(users, { status: inactive }); // 属性-值数组 remove(users, [type, guest]); // 属性名真值检查 remove(users, isDeleted);缺省谓词默认使用 identity当第二个参数省略时谓词默认为identity恒等函数此时所有真值元素会被删除假值元素0、false、null、undefined、、NaN得以保留。这一点在 remove.spec.ts 中有明确验证const array [0, 1, 2, null, 3, undefined, 4, false, 5, ]; const removed remove(array); expect(array).toEqual([0, null, undefined, false, ]); // 假值保留 expect(removed).toEqual([1, 2, 3, 4, 5]); // 真值被删除底层实现原理compat 层如何做到 Lodash 兼容理解remove的兼容性来源关键在于它的实现是两段式委托第一步iteratee 统一谓词形态src/compat/array/remove.ts 首先将传入的谓词交给iteratee做归一化转换src/compat/util/iteratee.tsexport function removeT( arr: ArrayLikeT, shouldRemoveElement: | ((value: T, index: number, arr: ArrayLikeT) boolean) | PartialT | [keyof T, unknown] | keyof T identity as any ): T[] { if (arr?.length null) { return []; } return removeToolkit(arr as T[], iteratee(shouldRemoveElement)); }iteratee的分派规则如下源码可见于 iteratee.tsvalue null未传或传null→ 返回identity传入函数→ 原样返回直接作为判定函数调用传入长度为 2 的数组→ 转换为matchesProperty(value[0], value[1])即属性-值对匹配传入其他对象→ 转换为matches(value)即部分对象匹配传入字符串/数字/symbol→ 转换为property(value)即按属性名取值并判定真值。其中matches、matchesProperty、property分别位于 src/compat/predicate/matches.ts、src/compat/predicate/matchesProperty.ts 与 src/compat/object/property.ts它们同样是兼容层中被find、filter、pullAllBy等众多函数复用的基础构件。第二步委托给主库的简单函数谓词版本归一化完成后兼容层把工作委托给主库实现removeToolkit即 src/array/remove.ts 导出的removeimport { remove as removeToolkit } from ../../array/remove.ts;主库版本只接受纯函数谓词其核心算法为先收集、后压缩用arr.slice()保留原始数组快照传给判定函数在遍历过程中把应保留的元素依次前移最终用arr.length resultIndex截断数组。值得注意的是遍历期间数组并未真正收缩而是等全部删除决策完成后再统一改写从而保证了判定函数观察到的始终是原始数组该行为同样被 remove.spec.ts 中 should not mutate the array until all elements to remove are determined 用例锁定。空值防护兼容层在入口处还做了防御性检查当arr?.length null即传入null或undefined时直接返回空数组[]。这与 Lodash 的行为一致测试用例也显式覆盖了这一场景remove(null, isEven)与remove(undefined)均返回[]。与主库es-toolkit/array版本的区别原文档开篇就用醒目的警告框强调了二者的取舍英文版见 docs/compat/reference/array/remove.md日文版即本文关联文档兼容层的remove为了支持多种谓词形态而实现得较为复杂主库的remove只支持简单的函数谓词因此运行更快。具体差异对照如下维度es-toolkit/compat的removees-toolkit/array的remove导入路径es-toolkit/compates-toolkit/array谓词形态函数 / 部分对象 / 属性-值对 / 属性名 / 缺省仅函数(value, index, array) boolean实现方式委托主库 iteratee归一化直接遍历压缩适用场景迁移 Lodash 代码、需要多种判定形态追求性能、判定逻辑简单明确例如主库版本的使用方式更简洁完整用法见 docs/reference/array/remove.mdimport { remove } from es-toolkit/array; // 删除偶数 const numbers [1, 2, 3, 4, 5]; const removedNumbers remove(numbers, value value % 2 0); console.log(numbers); // [1, 3, 5] console.log(removedNumbers); // [2, 4]在业务代码中如果只是为了按一个简单条件批量清理数组元素建议优先使用主库版本只有当需要从 Lodash 平滑迁移、或确实要使用部分对象/属性-值对等简写谓词时才引入es-toolkit/compat版本。两种remove的官方导出位置分别为 src/compat/compat.tsexport { remove } from ./array/remove.ts与 src/array/index.ts。边界行为与测试验证兼容层remove的边界语义大多继承了主库实现并在 src/compat/array/remove.spec.ts 中逐项验证判定函数参数每次调用收到(value, index, array)其中第三个参数是原始数组的快照副本且在遍历过程中保持不变稀疏数组holes删除操作会保留稀疏性——被删除位置对应的索引在新数组中仍不拥有属性测试中断言0 in array为false空位按undefined处理当谓词使用n null这类宽松判断时稀疏空位会被视为undefined参与判定删除发生在全部判定之后判定阶段数组未被改写因此基于索引的谓词如index % 2 0拿到的索引始终对应原始数组缺省谓词默认identity删除所有真值元素空/空值输入null、undefined返回[]。与filter等其他删除手段的取舍主库文档docs/reference/array/remove.md特别提示了一个关键区别remove是原地修改原数组的若不想改动原数组应改用filter。// 保留原数组生成新数组 const kept numbers.filter(n n % 2 ! 0);选择建议需要同时拿到被删元素和剩余元素且原数组允许被改写 → 用remove需要保留原数组、只生成过滤结果 → 用filter或es-toolkit的reject取反逻辑场景是删除所有等于某值的元素而非按条件判定 → 可考虑兼容层的pull、pullAll等专门函数。总结es-toolkit/compat的remove是对 Lodash_.remove的完整兼容实现它通过iteratee将函数、部分对象、属性-值对、属性名四种谓词形态统一归一再委托给主库的高效删除算法在兼容性与性能之间做出了清晰的分层。对正在从 Lodash 迁移的开发者它可以直接替换_.remove而无需改写调用代码对追求极致性能的新项目主库 src/array/remove.ts 的纯函数版本则是更优选择。【免费下载链接】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),仅供参考