ARTICLE DETAIL

资讯详情

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

es-toolkit 数组合并函数 zipWith 完全指南:用自定义函数组合多个数组

es-toolkit 数组合并函数 zipWith 完全指南:用自定义函数组合多个数组 es-toolkit 数组合并函数 zipWith 完全指南用自定义函数组合多个数组【免费下载链接】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-toolkitzipWith是 es-toolkit 提供的数组工具函数用于将多个数组中同一位置的元素按自定义规则组合成新数组。它是对基础zip的扩展zip只能把元素打包成元组而zipWith允许你传入一个combine函数直接对每个位置的元素进行求和、拼接、比较等任意变换。阅读本文后你将掌握zipWith的完整用法、参数细节、不等长数组的边界行为以及其底层实现与 lodash 兼容版本、函数式fp版本的区别。zipWith 是什么zipWith接收任意数量的数组和一个combine组合函数它把每个数组中相同索引的元素取出来一并传给combine函数再把combine的返回值收集成新数组返回。它的通用签名如下参见 官方文档const result zipWith(...arrs, combine);一个直观的类比是按行合并的拉链多个数组像拉链的齿一样对齐combine负责把同一行同一索引的齿焊接成一个新值。基本用法两个数值数组求和最常见的场景是把两个长度相同的数组按元素相加import { zipWith } from es-toolkit/array; zipWith([1, 2, 3], [4, 5, 6], (a, b) a b); // Returns: [5, 7, 9]三个及以上数组拼接字符串zipWith不限制数组数量三个数组同样可以直接组合import { zipWith } from es-toolkit/array; zipWith([a, b], [c, d], [e, f], (a, b, c) ${a}${b}${c}); // Returns: [ace, bdf]混合类型数组组合函数可以处理不同类型的数组。例如把数字和字符串拼成标签import { zipWith } from es-toolkit/array; zipWith([1, 2, 3], [a, b, c], (num, char) ${num}${char}); // Returns: [1a, 2b, 3c]不等长数组的处理以最长数组为准当传入的数组长度不一致时zipWith会以最长数组的长度为准生成结果较短数组中缺失的位置会以undefined传入combine函数。因此可以在组合函数内部用??等操作符做兜底import { zipWith } from es-toolkit/array; zipWith([1, 2], [10, 20, 30], (a, b) (a ?? 0) (b ?? 0)); // Returns: [11, 22, 30]上例中第三轮组合时第一个数组没有第 3 个元素a为undefined通过(a ?? 0)兜底为 0得到0 30 30。这一行为在 src/array/zipWith.ts 的实现中得到了验证实现首先计算所有数组长度的最大值Math.max(...arrs.map(arr arr.length))并据此预分配结果数组随后逐索引取出各数组的元素arrs.map(arr arr[i])缺失位置自然得到undefined调用combine(...elements, i)填充结果。参数与返回值详解zipWith的参数与返回值约定如下来自 官方文档项目说明arrsArrayreadonly T[]需要合并的多个数组均为只读数组类型不会被修改combine(...items: [...T[], number]) R组合函数。接收每个数组同一索引位置的元素以及该索引值本身作为最后一个参数返回一个新值返回值R[]由combine的返回值构成的新数组值得注意的关键点combine的最后一个参数是当前索引index这一点在 src/array/zipWith.ts 的实现中体现为result[i] combine(...elements, i)——即调用时把各数组元素展开后再追加索引i。该行为也有对应的测试用例验证见 src/array/zipWith.spec.tsit(should provide index parameter to combine function, () { const result zipWith([10, 20, 30], [1, 2, 3], (a, b, index) a b index); expect(result).toEqual([11, 23, 35]); });源码级剖析重载与实现多个类型安全的重载在 src/array/zipWith.ts 中函数定义了一组重载签名分别支持 1 个、2 个、3 个、4 个数组每种重载都推导出独立的泛型参数T、U、V、W从而保证combine的参数类型与各数组元素类型一一对应、完全类型安全export function zipWithT, R(arr1: readonly T[], combine: (item: T, index: number) R): R[]; export function zipWithT, U, R( arr1: readonly T[], arr2: readonly U[], combine: (item1: T, item2: U, index: number) R ): R[]; // ...3 个、4 个数组的重载同理实际的合并逻辑最终实现通过 rest 参数吸收所有入参将最后一个参数视为combine其余视为待合并的数组export function zipWithT, R(arr1: readonly T[], ...rest: any[]): R[] { const arrs [arr1, ...rest.slice(0, -1)]; const combine rest[rest.length - 1] as (...items: any[]) R; const maxIndex Math.max(...arrs.map(arr arr.length)); const result: R[] Array(maxIndex); for (let i 0; i maxIndex; i) { const elements: T[] arrs.map(arr arr[i]); result[i] combine(...elements, i); } return result; }从实现可以看出两个细节一是结果数组用Array(maxIndex)预分配避免反复扩容二是整体为单次线性遍历时间复杂度为O(n × k)n为最长数组长度k为数组个数。单元测试覆盖src/array/zipWith.spec.ts 覆盖了核心行为单数组 恒等函数zipWith([1, 2, 3], x x)返回原数组两数组、三数组的常规组合不等长数组时缺失位补undefined[1a, 2b, 3undefined]combine能收到索引参数。lodash 兼容版本compat更宽松的入参约定es-toolkit 提供了与 lodash 行为对齐的兼容版本位于 src/compat/array/zipWith.ts可通过es-toolkit/compat导入。它与标准版本的主要差异在于接受ArrayLike类型如arguments对象、类数组作为入参允许传入null/undefined/ 空参此时返回空数组见 src/compat/array/zipWith.spec.tscombine可以省略传入null/undefined或不传此时退化为普通zip行为返回分组后的元组数组内部复用unzip先做转置再用map逐个调用iteratee实现更贴近 lodash 的思路export function zipWithT, R(...combine: Array((...group: T[]) R) | ArrayLikeT | null | undefined): R[] { let iteratee combine.pop(); if (!isFunction(iteratee)) { combine.push(iteratee); iteratee undefined; } if (!combine?.length) { return []; } const result unzip(combine as ArrayLikeArrayLikeT); if (iteratee null) { return result as R[]; } return result.map(group iteratee(...group)) as R[]; }其测试还验证了只传函数不传数组时返回空数组的行为src/compat/array/zipWith.spec.ts。函数式版本fp支持管道调用es-toolkit 的函数式版本位于 src/fp/array/zipWith.ts可通过es-toolkit/fp导入。它将数组参数柯里化适合配合pipe使用先传入待合并的数组与combine返回一个接收主数组的新函数import { pipe, zipWith } from es-toolkit/fp; pipe([1, 2], zipWith((value, index) value index)); // [1, 3] // 预先配置第二个数组 const combineWithB zipWith([a, b], (a, b) ${a}${b}); combineWithB([1, 2]); // [1a, 2b]其实现本质是薄封装把参数原样转交给标准版zipWith见 src/fp/array/zipWith.ts。与相关函数的对照与选择建议在 src/array/index.ts 中zipWith与zip、unzipWith一同从es-toolkit/array入口导出三者可以对照理解函数行为适用场景zip按索引打包成元组数组只需简单聚合后续再自行处理zipWith按索引组合后立即应用combine一步完成变换代码更紧凑unzipWithzipWith的逆操作用函数合并组处理已分组的数据典型应用向量/坐标运算zipWith(vecA, vecB, (a, b) a b)实现逐元素加法数据行合并把 ID 数组、名称数组、状态数组按索引合并成对象数组批量格式化多个字段数组拼接成模板字符串矩阵转置后聚合配合zip或unzip对分组数据做汇总。小结zipWith以多个数组 一个组合函数的简洁模型覆盖了按位合并数组的绝大多数需求。标准版es-toolkit/array类型安全、实现精简兼容版es-toolkit/compat对齐 lodash 语义容忍null/undefined与类数组函数式版es-toolkit/fp则无缝融入管道式编程。理解其以最长数组为准、缺失位补undefined、combine尾参为索引三条核心规则即可在各类数据合并场景中自如使用。【免费下载链接】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),仅供参考
返回列表