es-toolkit/fp 的 dropRight 使用指南:在 pipe 流水线中从数组末尾裁剪元素
2026/9/16 20:25:46 网站建设 项目流程

es-toolkit/fp 的 dropRight 使用指南:在 pipe 流水线中从数组末尾裁剪元素

【免费下载链接】es-toolkitA modern JavaScript utility library that's 2-3 times faster and up to 97% smaller, a major upgrade to lodash.项目地址: https://gitcode.com/GitHub_Trending/es/es-toolkit

导读

dropRight是 es-toolkit 函数式编程入口es-toolkit/fp提供的数组操作算子:调用dropRight(count)会返回一个新函数,该函数接收数组并移除其末尾的count个元素。与普通(data-first)的dropRight不同,fp 版采用>const result = pipe(array, dropRight(count));

官方文档特别提示了选用原则(见 docs/fp/reference/dropRight.md 与日文版 docs/ja/fp/reference/dropRight.md):

  • 在普通代码(不组合流水线)中,建议直接使用 es-toolkit 原始的>import { dropRight, pipe } from 'es-toolkit/fp'; pipe([1, 2, 3, 4], dropRight(2)); // => [1, 2]

    dropRight(2)单独取出来看,它就是一个等待数据的函数,这正是 fp 算子「配置与数据分离」的体现:

    const dropLastTwo = dropRight(2); // (array: readonly number[]) => number[] dropLastTwo([1, 2, 3, 4]); // => [1, 2] pipe([1, 2, 3, 4], dropLastTwo); // 与上面等价

    参数

    • countnumber):需要从数组末尾移除的元素个数。

    返回值

    (array: readonly T[]) => T[]:一个将readonly T[]映射为「剩余元素数组」的函数。输入数组只读即可,输出是全新的数组,不会修改原数组。

    组合示例:与其它 fp 算子串联

    dropRight的典型价值体现在流水线中——先截断、再变换,一气呵成:

    import { dropRight, map, pipe, take } from 'es-toolkit/fp'; const result = pipe( [1, 2, 3, 4, 5, 6], dropRight(2), // => [1, 2, 3, 4] map(x => x * 10), // => [10, 20, 30, 40] take(2) // => [10, 20] ); // => [10, 20]

    这段代码展示了 fp 入口的核心优势(详见 docs/fp/intro.md):每一步从上到下按执行顺序阅读,无需解析嵌套调用,也无需为中间结果创建临时变量。

    源码实现解析:fp 封装与核心算法

    fp 版dropRight的实现非常简洁,它只是对普通版dropRight的柯里化封装。完整实现位于 src/fp/array/dropRight.ts:

    import { dropRight as dropRightToolkit } from '../../array/dropRight.ts'; export function dropRight<T>(count: number): (array: readonly T[]) => T[] { return function (array: readonly T[]): T[] { return dropRightToolkit(array, count); }; }

    可以看出:

    1. dropRight(count)闭包捕获count,返回一个等待数组的新函数;
    2. 真正的裁剪逻辑完全复用于普通版 src/array/dropRight.ts,fp 层不重复实现任何算法——这与 docs/fp/intro.md 中「es-toolkit/fp复用es-toolkit的实现,只改变调用方式」的描述完全一致。

    普通版dropRight的核心算法如下(src/array/dropRight.ts):

    export function dropRight<T>(arr: readonly T[], itemsCount: number): T[] { itemsCount = Math.min(-itemsCount, 0); if (itemsCount === 0) { return arr.slice(); } return arr.slice(0, itemsCount); }

    这里有一个巧妙的小技巧:Math.min(-itemsCount, 0)会对itemsCount取反并钳制到不大于 0,从而把「负数与 0 的输入」统一归一化为0(此时直接返回arr.slice()的副本),把「正数输入」转换为负的切片终点,最后通过arr.slice(0, itemsCount)一次性返回新数组。由于slice的终点是负数时会从数组末尾向前计算,dropRight([1, 2, 3, 4, 5], 2)实际等价于[1, 2, 3, 4, 5].slice(0, -2),得到[1, 2, 3]

    该函数在 fp 数组模块的入口 src/fp/array/index.ts 中被导出,因此可以像import { dropRight, pipe } from 'es-toolkit/fp'这样直接使用。

    边界情况与测试验证

    普通版dropRight的边界行为在 src/array/dropRight.spec.ts 中得到了系统性的测试覆盖,这些行为同样适用于 fp 版(fp 版直接委托给普通版实现):

    场景输入结果说明
    常规裁剪dropRight([1.2, 2.3, 3.4], 1)[1.2, 2.3]移除末尾 1 个元素
    移除 0 个dropRight([1.2, 2.3, 3.4], 0)[1.2, 2.3, 3.4]返回完整数组
    负数输入dropRight([1.2, 2.3, 3.4], -1)[1.2, 2.3, 3.4]负数视为 0,不裁剪
    小数输入dropRight([1.2, 2.3, 3.4], 1.5)[1.2, 2.3]slice内部做整数化处理
    超出长度dropRight([1.2, 2.3, 3.4], 4)[]移除数量不小于长度时返回空数组
    原数组不变始终返回新数组,不改动输入

    fp 版自身的冒烟测试位于 src/fp/array/dropRight.spec.ts,验证了其在 pipe 中的基本行为:

    import { describe, expect, it } from 'vitest'; import { dropRight } from './dropRight.ts'; import { pipe } from '../pipe.ts'; describe('dropRight', () => { it('works in a pipe', () => { expect(pipe([1, 2, 3, 4], dropRight(2))).toEqual([1, 2]); }); });

    与 pipe 的关系:惰性求值视角

    理解 fp 版dropRightpipe中的行为,还需要知道pipe的执行模型。从 src/fp/pipe.ts 的实现在看,pipe会把传入的函数按「是否支持惰性」分组:连续的惰性算子(如mapfiltertake)会被融合成单次遍历;其余函数则逐个依次应用。

    dropRight本身没有标记lazy属性(从 src/fp/array/dropRight.ts 可以看到它只是一个普通函数,并未携带lazy元数据),因此它属于「急切(eager)」路径——在 pipe 中作为独立一步执行,返回完整的新数组后再交给下一步。这也符合它的语义:裁剪末尾元素必须知道整个数组的长度,天然无法像take那样提前短路。因此在使用时无需为性能担心:当pipe中同时存在mapfiltertake等惰性算子时,它们之间仍会进行单遍融合优化(参见 src/fp/pipe.ts 的文档注释),dropRight只是作为普通步骤参与其中。

    总结

    • fp 版dropRight(count)返回一个 contenteditable="false">【免费下载链接】es-toolkitA modern JavaScript utility library that's 2-3 times faster and up to 97% smaller, a major upgrade to lodash.项目地址: https://gitcode.com/GitHub_Trending/es/es-toolkit

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询