资讯中心

es-toolkit 函数式编程指南:使用 fp/sampleSize 在 pipe 管道中随机采样

📅 2026/9/30 5:19:27
es-toolkit 函数式编程指南:使用 fp/sampleSize 在 pipe 管道中随机采样
es-toolkit 函数式编程指南使用 fp/sampleSize 在 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-toolkitsampleSize函数式编程版是 es-toolkitfp子模块提供的随机采样算子它返回一个等待数据的函数可从传入的数组中随机取出指定数量、且不重复数组位置的元素专为与pipe组合使用而设计。读完本文你将掌握fp/sampleSize的完整调用签名、边界行为与异常规则并透过源码理解其基于 Floyd 算法与randomInt的底层实现以及它与普通版sampleSize的差异和选型依据。一、函数式变体与普通版的关系在 es-toolkit 中普通版sampleSize采用数据优先的调用方式sampleSize(array, size)而函数式编程版es-toolkit/fp的sampleSize采用数据置后data-last的柯里化形态用于在pipe中作为变换步骤使用。形态调用方式适用场景普通版sampleSize(array, size)普通代码中直接调用fp 变体pipe(array, sampleSize(size))用pipe组合多个变换步骤时正如docs/fp/reference/sampleSize.md中的提示所强调在普通代码中应优先使用原始版sampleSize只有在用pipe组合变换时才使用 fp 变体。fp 变体并不重复实现采样逻辑而是对普通版的一层薄封装thin wrapper。二、基本用法import { pipe, sampleSize } from es-toolkit/fp; const values pipe([1, 2, 3, 4], sampleSize(2)); // values 长度为 2元素均来自输入数组从src/fp/array/sampleSize.ts的源码可以看到 fp 变体的实现非常简洁它接收size作为配置参数返回一个等待数组的函数该函数在收到数组后转发给普通版实现export function sampleSizeT(size: number): (array: readonly T[]) T[] { return function (array: readonly T[]): T[] { return sampleSizeToolkit(array, size); }; }这种先传配置、后传数据的模式正是es-toolkit/fp的通用设计每个 fp 函数先接收配置如map(fn)、take(2)、sampleSize(2)返回一个接收数据的函数再由pipe把上一步的输出作为下一步的输入依次贯穿。fp 变体同样通过src/fp/index.ts与src/fp/array/index.ts统一导出。三、参数与返回值参数sizenumber要从数组中随机取出的元素个数。返回值(array: readonly T[]) T[]一个将readonly T[]映射为随机元素数组的函数即等待pipe喂入数据的变换步骤。抛出异常如果size大于传入数组的长度会抛出错误。// 抛出 Error: Size must be less than or equal to the length of array. pipe([1, 2, 3], sampleSize(4));四、语义与边界行为sampleSize返回size个来自输入数组的随机值不会重复选择同一个数组位置即无放回采样。结合普通版文档docs/reference/array/sampleSize.md与测试用例可以确认以下边界行为size为 0返回空数组[]不会报错size等于数组长度等价于洗牌shuffle效果返回一个包含全部元素但顺序随机的新数组——注意它返回的是新数组与原数组不是同一引用result.not.toBe(array)size大于数组长度抛出Error错误消息为Size must be less than or equal to the length of array.不修改原数组函数返回新数组输入数组保持不变。这些行为在src/array/sampleSize.spec.ts中均有测试覆盖例如it(returns the same array if the size is equal to the array length, () { const array [1, 2, 3]; const result sampleSize(array, array.length); expect(result).toEqual(array); expect(result).not.toBe(array); });fp 变体的测试src/fp/array/sampleSize.spec.ts则验证了在pipe中使用的效果结果长度为size且所有元素均来自输入数组。五、底层实现原理Floyd 算法普通版sampleSize位于src/array/sampleSize.ts其核心采用Floyd 算法Robert Floyd 提出的无放回随机采样算法在保证不重复选中的同时保持高效的线性复杂度export function sampleSizeT(array: readonly T[], size: number): T[] { if (size array.length) { throw new Error(Size must be less than or equal to the length of array.); } const result new Array(size); const selected new Set(); for (let step array.length - size, resultIndex 0; step array.length; step, resultIndex) { let index randomInt(0, step 1); if (selected.has(index)) { index step; } selected.add(index); result[resultIndex] array[index]; } return result; }算法要点预分配结果数组const result new Array(size)避免动态扩容去重集合const selected new Set()记录已选中的下标增量随机范围循环从array.length - size步进到array.length每一步用randomInt(0, step 1)生成一个半开区间[0, step 1)内的随机整数下标冲突处理若生成的下标已被选中则退化为使用当前step下标从而保证不重复、且一定能在size步内填满结果随机数来源randomInt见src/math/randomInt.ts基于random并向下取整返回[minimum, maximum)之间的随机整数。由于每一步都能在常数时间内完成Set的has/add平均为 O(1)整个采样过程的时间复杂度为 O(n)其中 n 为采样规模size。六、在 pipe 管道中组合使用es-toolkit/fp的核心入口是pipe其实现位于src/fp/pipe.ts。pipe将数据从左到右依次穿过每个函数把嵌套调用f(g(h(x)))改写为自上而下的顺序步骤。sampleSize(size)返回的正是等待数据的一元函数因此可以自然地插入管道中的任何位置例如先过滤再采样import { pipe, filter, sampleSize } from es-toolkit/fp; // 从 1~100 中先筛出偶数再随机取 5 个 const result pipe( Array.from({ length: 100 }, (_, i) i 1), filter(x x % 2 0), sampleSize(5) ); // 结果长度为 5元素均为偶数需要说明的是sampleSize本身是非惰性eager算子它必须消费完整数组才能完成无放回采样因此不会参与pipe的惰性融合lazy fusion优化路径当pipe检测到连续惰性算子如map、filter、take时才会融合为单趟遍历并支持提前终止详见src/fp/pipe.ts中的chunkFunctions与lazyPipe。当sampleSize与其他惰性算子混用时pipe会按连续惰性算子组分段处理非惰性步骤按普通一元函数逐一执行行为与直接调用一致。七、典型应用场景问卷调查抽样从候选题目或样本池中随机抽取指定数量的条目游戏随机道具/对手从物品列表或玩家列表中随机选出多个不重复元素数据降采样从大数据集中随机选取子集用于测试或演示洗牌令size等于数组长度即得到一次完整的随机重排。八、小结fp/sampleSize是普通版sampleSize的 contenteditable="false">【免费下载链接】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),仅供参考

看完文章,想为自己的企业也做一次专业网站诊断?

尧图顾问免费为您评估现有网站,并给出建站/改版建议与报价方案。

免费获取方案