十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

es-toolkit/fp 的 maxBy:在函数式管道中选出最大值的正确姿势

es-toolkit/fp 的 maxBy:在函数式管道中选出最大值的正确姿势 es-toolkit/fp 的 maxBy在函数式管道中选出最大值的正确姿势【免费下载链接】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本篇指南聚焦 es-toolkit 函数式编程子模块es-toolkit/fp中的maxBy操作符它创建一个返回计算得分最大元素的函数专用于与pipe组合实现数据流式处理。读完本文你将掌握 fp 版maxBy的调用约定、参数与返回值类型、空数组与 NaN 等边界行为以及它与普通版maxBy在何时该用哪一个的取舍。概述一个为 pipe 而生的函数es-toolkit/fp是一套data-last数据置后风格的函数式编程 API。所谓>const result pipe(array, maxBy(getValue));它本身不直接接收数组而是接收一个用于计算得分的getValue函数返回一个把readonly T[]映射为最大元素或undefined的函数。这与普通版maxBy(items, getValue)的参数顺序数据在前、配置在后正好相反。使用法管道中的一行调用在管道中maxBy会对流入数组的每个元素调用getValue并返回计算结果最大的那个元素若数组为空则返回undefinedimport { maxBy, pipe } from es-toolkit/fp; pipe( [{ score: 10 }, { score: 30 }, { score: 20 }], maxBy(item item.score) ); // { score: 30 }其行为可以概括为对数组每个元素调用getValue取其数值结果返回数值结果最大的那个原始元素而不是得分本身数组为空时返回undefined。参数getValue(item: T) number返回用于比较的数值的函数。值得补充的是虽然文档以(item: T) number简写但源码中的完整签名还向getValue传递了索引与数组本身两个附加参数。见 fp 实现getValue: (element: T, index: number, array: readonly T[]) number这意味着在管道里同样可以写出依赖下标或整数组的得分函数例如maxBy((item, index) item.value index)。返回值(array: readonly T[]) T | undefined一个把readonly T[]映射为最大元素或undefined的函数。注意getValue返回的是 number 类型这是与处理 bigint 等类型的其他实现的一个重要区别。空数组与非空数组两个重载fp 版maxBy在类型层面为调用者提供了两组重载见 src/fp/array/maxBy.ts// 非空数组元组类型保证返回 T export function maxByT( getValue: (element: T, index: number, array: readonly T[]) number ): (array: readonly [T, ...T[]]) T; // 一般数组可能为空返回 T | undefined export function maxByT( getValue: (element: T, index: number, array: readonly T[]) number ): (array: readonly T[]) T | undefined;也就是说当你传入的数组在类型上被标注为非空如readonly [T, ...T[]]时TypeScript 能推断出结果必然存在而普通T[]数组则可能得到undefined编译器会强制你处理空数组分支。这是 es-toolkit 在类型安全上的细节设计从源码的重载签名可以直接确认。底层实现它只是普通 maxBy 的柯里化包装fp 版maxBy的完整实现非常精简src/fp/array/maxBy.ts#L42-L48export function maxByT( getValue: (element: T, index: number, array: readonly T[]) number ): (array: readonly T[]) T | undefined { return function (array: readonly T[]): T | undefined { return maxByToolkit(array, getValue); }; }它只是把普通版maxBy从../../array/maxBy.ts导入做了一次数据后置的柯里化封装先捕获getValue返回的闭包在收到数组后再以maxByToolkit(array, getValue)调用真正的实现。因此两者的算法与边界行为完全一致fp 版不引入任何额外的排序或复制逻辑保持了 es-toolkit 一贯的轻量特性。核心算法单次遍历 从 -Infinity 起步普通版maxBy的算法位于 src/array/maxBy.ts#L74-L100要点如下if (items.length 0) { return undefined; } let maxElement items[0]; let max -Infinity; for (let i 0; i items.length; i) { const element items[i]; const value getValue(element, i, items); if (Number.isNaN(value)) { return element; } if (value max) { max value; maxElement element; } } return maxElement;几个值得注意的实现细节单次线性遍历时间复杂度 O(n)不产生中间数组初始最大值设为-Infinity保证任何有限数都能被选中由于比较用的是严格并列最大值时返回先出现的元素首个最大元素NaN 传播一旦某个元素的得分是NaN立即返回该元素本身这与原生Math.max的 NaN 行为一致——这一点在测试中有专门用例覆盖src/array/maxBy.spec.ts#L38-L42无论 NaN 出现在数组的什么位置都会传播getValue会被调用时传入(element, index, array)三个参数对应测试中的 index 与 array 用例src/array/maxBy.spec.ts#L44-L54。fp 版与普通版何时用哪个maxBy在 es-toolkit 中存在两个入口使用建议非常明确场景推荐 API导入路径普通命令式代码直接对数组求最大值普通版maxByes-toolkit/array或es-toolkit用pipe组合多个变换的流水线fp 版maxByes-toolkit/fp普通代码中直接用数据在前的普通版更直观import { maxBy } from es-toolkit/array; const people [ { name: john, age: 30 }, { name: jane, age: 28 }, { name: joe, age: 26 }, ]; maxBy(people, person person.age); // { name: john, age: 30 }而当你想把取最大值作为流水线的一环、与其他操作符如filter、map、sortBy等串联时则应该使用 fp 版让pipe把前一步的输出作为数组喂给maxBy。普通版的完整用法与更多示例可参考 普通版 maxBy 文档。在 pipe 流水线中的实战组合把maxBy放进管道可以写出可读性很强的声明式数据处理流程。例如从一批商品中筛选出有效商品再找出评分最高者import { pipe, filter, maxBy } from es-toolkit/fp; const products [ { name: A, price: 100, rating: 4.2 }, { name: B, price: 200, rating: 4.8 }, { name: C, price: 50, rating: 3.9 }, ]; pipe( products, filter(product product.price 0), maxBy(product product.rating) ); // { name: B, price: 200, rating: 4.8 }注意一个细节fp 版的maxBy本身不是惰性操作符它没有lazy属性因此它属于pipe中的普通求值函数会在其位置被逐个应用到当前数据上。与之相对map、filter、take等惰性函数在连续出现时会被pipe融合成单趟短路遍历。这不影响正确性只是说明maxBy作为聚合操作符天然需要消费完整数组后才能给出答案。对于对称的取最小得分需求fp 版还提供了minBy调用约定与maxBy完全一致只是返回得分最小的元素。小结fp 版maxBy(getValue)返回一个函数供pipe流水线使用data-last 风格与普通版相反对每个元素调用getValue取数值得分返回得分最大的原始元素空数组返回undefined类型重载区分非空数组与可能为空的数组非空元组类型下结果被推断为必存在底层就是对普通版maxBy的柯里化包装src/fp/array/maxBy.ts算法为单次遍历、初始值-Infinity、并列取首个、NaN 传播与Math.max语义一致普通代码用es-toolkit/array的maxBy组合变换时用es-toolkit/fp的maxBy。相关实现与测试fp 封装 src/fp/array/maxBy.ts、普通版实现 src/array/maxBy.ts、fp 测试 src/fp/array/maxBy.spec.ts、普通版测试 src/array/maxBy.spec.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),仅供参考
返回列表