es-toolkit 数组分区函数 partition 完整指南:类型、原理与用法

es-toolkit 数组分区函数 partition 完整指南:类型、原理与用法 es-toolkit 数组分区函数 partition 完整指南类型、原理与用法【免费下载链接】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-toolkitpartition是 es-toolkit 提供的一个实用数组工具函数它根据一个条件函数将数组拆分成两组满足条件的元素进入第一组不满足的进入第二组最终返回一个包含两个数组的元组。本文将围绕 docs/ja/reference/array/partition.md 的官方说明结合仓库源码与测试用例带你掌握partition的 API 细节、TypeScript 类型推断能力、底层实现原理以及它在函数式fp、迭代器iterator和 Lodash 兼容compat模块中的变体用法。一、partition 是什么partition接收一个数组和一个条件函数predicate返回[truthy, falsy]这样的二元元组第一个数组包含条件函数返回真值truthy的元素第二个数组包含返回假值falsy的元素。const [truthy, falsy] partition(arr, isInTruthy);它与filter的核心区别在于filter只保留满足条件的元素丢弃其余部分而partition同时保留两组一次遍历即可把数据按条件“一分为二”非常适合在后续流程中分别处理两类数据。二、基本用法从es-toolkit/array子路径导入partitionimport { partition } from es-toolkit/array; // 将数值数组拆分为偶数和奇数 const numbers [1, 2, 3, 4, 5, 6]; const [evens, odds] partition(numbers, x x % 2 0); // evens: [2, 4, 6] // odds: [1, 3, 5] // 将对象数组按特定条件拆分 const users [ { name: Alice, active: true }, { name: Bob, active: false }, { name: Charlie, active: true }, ]; const [activeUsers, inactiveUsers] partition(users, user user.active); // activeUsers: [{ name: Alice, active: true }, { name: Charlie, active: true }] // inactiveUsers: [{ name: Bob, active: false }]当传入空数组时返回两个空数组import { partition } from es-toolkit/array; const [truthy, falsy] partition([], x x 0); // truthy: [] // falsy: []三、参数与返回值partition(arr, isInTruthy)arrT[]需要拆分成两组的数组。isInTruthy(value: T, index: number, array: readonly T[]) unknown决定每个元素进入第一组truthy还是第二组falsy的条件函数。条件函数会被依次调用并传入三个参数——当前元素的值value、元素下标index以及整个数组array。这一点与Array.prototype.filter的回调签名保持一致。返回值是一个由两个数组组成的元组[truthy: T[], falsy: T[]]第一组包含条件为真的元素第二组包含条件为假的元素。两组都保持原数组中的相对顺序。四、底层实现原理partition的实现非常简洁位于 src/array/partition.ts。核心逻辑是初始化两个空数组用for循环遍历输入数组对每个元素调用条件函数根据返回值决定push到哪个分组export function partitionT( arr: readonly T[], isInTruthy: (value: T, index: number, array: readonly T[]) unknown ): [truthy: T[], falsy: T[]] { const truthy: T[] []; const falsy: T[] []; for (let i 0; i arr.length; i) { const item arr[i]; if (isInTruthy(item, i, arr)) { truthy.push(item); } else { falsy.push(item); } } return [truthy, falsy]; }从源码结构可以推断几个重要特性单次遍历O(n) 时间复杂度每个元素只被访问一次条件函数也恰好调用 n 次。不使用高阶数组方法实现选择了显式for循环而非filterreduce的组合避免了额外的函数调用开销这也是 es-toolkit 追求性能的一种典型写法。接受readonly数组参数类型为readonly T[]因此即使传入as const定义的只读数组也不会报类型错误。条件函数返回unknown返回值不要求必须是布尔值任何 truthy/falsy 值如数字、字符串、对象都会被正确分组行为与Array.prototype.filter一致。测试用例佐证src/array/partition.spec.ts 中的测试覆盖了关键行为基础分组partition([true, true, false], x x)返回[[true, true], [false]]对象数组按属性分组条件函数能收到正确的index测试断言indices依次为[0, 1, 2, 3, 4]条件函数收到的第三个参数就是原数组本身arrays.forEach(array expect(array).toBe(arr))条件函数返回任意 truthy/falsy 值如i i.good其中good为可选布尔属性时行为与filter一致。五、TypeScript 类型守卫与类型收窄partition在 src/array/partition.ts 中声明了两个重载这是它区别于普通filter的关键能力重载一类型守卫type guard当条件函数被声明为类型守卫value is U时返回元组的类型会被精确收窄export function partitionT, U extends T( arr: readonly T[], isInTruthy: (value: T, index: number, array: readonly T[]) value is U ): [truthy: U[], falsy: ArrayExcludeT, U];第一组是U[]满足守卫类型的元素第二组是ArrayExcludeT, U排除U后的其余元素。重载二普通条件函数export function partitionT( arr: readonly T[], isInTruthy: (value: T, index: number, array: readonly T[]) unknown ): [truthy: T[], falsy: T[]];两组类型都为T[]。测试用例展示了实际效果。对只读窄类型数组使用类型守卫const arr [1, 2, 3, 4, 5] as const; const isOdd (num: number): num is 1 | 3 | 5 num % 2 1; const [odds, evens] partition(arr, isOdd); // odds: Array1 | 3 | 5 // evens: Array2 | 4从测试expectTypeOf(evens).toEqualTypeOfArray2 | 4()可以看出两个分组的类型都被精确收窄这为后续的类型安全处理提供了保障。六、函数式版本es-toolkit/fp在函数式编程风格下src/fp/array/partition.ts 提供的是柯里化形式先传入条件函数返回一个接收数组、返回分组元组的新函数方便与pipe组合import { partition, pipe } from es-toolkit/fp; pipe([1, 2, 3, 4], partition(value value % 2 0)); // [[2, 4], [1, 3]] // 配合类型守卫使用 const isString (value: string | number): value is string typeof value string; pipe([1, a, 2, b], partition(isString)); // [[a, b], [1, 2]]该变体同样支持类型守卫重载且内部实现就是直接复用es-toolkit/array的partitionreturn function (array: readonly T[]): [truthy: T[], falsy: T[]] { return partitionToolkit(array, predicate); };七、迭代器版本es-toolkit/iterator对于迭代器数据源src/iterator/partition.ts 提供了一个终端操作terminal operation版本的partition它会消费整个迭代器把满足条件的元素放入第一组其余放入第二组并保持组内相对顺序。partition([1, 2, 3, 4].values(), x x % 2 0); // [[2, 4], [1, 3]]该实现的几个细节值得注意条件函数签名是(value: T, index: number) boolean使用while (!next.done)循环逐项拉取迭代器若条件函数抛错会调用source.return?.()显式关闭迭代器后再重新抛出异常见 src/iterator/partition.ts由于它是终端操作会拉取全部元素不能用于无限迭代器。八、Lodash 兼容版本es-toolkit/compat如果你从 lodash 迁移src/compat/array/partition.ts 提供了与 lodash_.partition行为一致的兼容实现从es-toolkit/compat导入import { partition } from es-toolkit/compat; // 函数条件 partition([1, 2, 3, 4, 5, 6], n n % 2 0); // [[2, 4, 6], [1, 3, 5]] // 属性名简写 const users [ { name: john, active: true }, { name: jane, active: false }, { name: bob, active: true }, ]; partition(users, active); // [[{ name: john, active: true }, { name: bob, active: true }], [{ name: jane, active: false }]] // 对象简写 partition(users, { active: true }); // 属性值数组简写 partition(users, [name, john]); // 对普通对象按值分组 const obj { a: { score: 90 }, b: { score: 40 }, c: { score: 80 } }; partition(obj, item item.score 80); // [[{ score: 90 }, { score: 80 }], [{ score: 40 }]] // null / undefined 按空数组处理 partition(null, x x 0); // [[], []] partition(undefined, active); // [[], []]compat 版本的predicate参数支持四种形式函数、部分对象PartialT、属性值数组[PropertyKey, any]、属性名PropertyKey默认值为identity。这些简写形式会经由 src/compat/util/iteratee.ts 统一转换为判定函数。需要说明的是官方文档在 docs/compat/reference/array/partition.md 中给出了明确建议由于 compat 版本需要处理null/undefined和多种 predicate 类型运行速度较慢如果不需要 lodash 兼容性应优先使用更快、更现代的 es-toolkit 原生 partition。九、如何选择合适的分区 API场景推荐导入路径特点普通数组分区追求性能与类型收窄es-toolkit/array原生实现支持类型守卫单次遍历函数式组合pipe/flowes-toolkit/fp柯里化先传条件函数再传数组迭代器数据源一次性消费es-toolkit/iterator终端操作自动关闭出错的迭代器从 lodash 迁移需要简写形式es-toolkit/compat支持属性名/对象/数组简写兼容null无论选择哪个入口partition都保持了一组满足条件、一组不满足条件、顺序不变的一致语义。对于绝大多数现代 JavaScript/TypeScript 项目推荐直接使用es-toolkit/array的原生版本配合 TypeScript 类型守卫可以获得最精确的静态类型推导同时获得最小的打包体积与最优的运行性能。【免费下载链接】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),仅供参考