
es-toolkit unzipWith 详解为数组解组与重组注入自定义转换函数【免费下载链接】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-toolkitunzipWith是 es-toolkit 数组模块中用于解组unzip并转换的核心工具它把多个数组拼接成的二维数组按相同位置重新聚合成组再交给自定义的iteratee函数完成转换最终返回全新的结果数组。本文基于 官方日语文档 展开结合仓库源码与测试用例完整讲解它的签名、边界行为、源码实现原理以及与unzip/zip的协同用法。快速概览unzipWith的调用形式非常简单const transformedArray unzipWith(target, iteratee);它接收一个多个数组拼接在一起的二维数组作为输入先将各内部数组同一位置的元素收集成一个小组再把每个小组整体传给iteratee用其返回值组成新数组。可以把它理解为unzipmap的组合unzip负责重排iteratee负责变换。使用方式函数签名与参数说明unzipWith(target, iteratee)接受两个参数参数类型说明targetreadonly T[][]待解组并转换的二维数组由多个内部数组拼接而成iteratee(...args: T[]) R转换函数接收同一位置的一组元素返回一个新的值返回值类型为R[]即由转换函数结果构成的新数组。典型场景同位置元素聚合计算文档给出了三个最具代表性的用法。场景一把同位置的数值相加import { unzipWith } from es-toolkit/array; // 相同位置的数値相加 const numbers [ [1, 2], [3, 4], [5, 6], ]; const sums unzipWith(numbers, (a, b, c) a b c); console.log(sums); // [9, 12] (1359, 24612)场景二把同位置的字符串拼接import { unzipWith } from es-toolkit/array; const words [ [hello, world], [foo, bar], [es, toolkit], ]; const combined unzipWith(words, (a, b, c) a b c); console.log(combined); // [hellofooes, worldbartoolkit]场景三对对象数组求属性平均值import { unzipWith } from es-toolkit/array; const scores [ [{ score: 80 }, { score: 90 }], [{ score: 85 }, { score: 95 }], [{ score: 75 }, { score: 88 }], ]; const averages unzipWith(scores, (a, b, c) (a.score b.score c.score) / 3); console.log(averages); // [80, 91] ((808575)/3, (909588)/3)从源码src/array/unzipWith.ts可以看到unzipWith并不要求内部数组等长因此上述示例中iteratee的每个参数对应一条内部数组内部数组数量与iteratee参数个数天然对应。边界行为详解内部数组长度不一致不足位置以undefined补足unzipWith的结果长度由最长的内部数组决定较短内部数组缺失的位置会以undefined传给iterateeimport { unzipWith } from es-toolkit/array; const mixed [ [1, 4], [2, 5], [3], // 长度不同 ]; const result unzipWith(mixed, (a, b, c) { // c 有可能是 undefined return (a || 0) (b || 0) (c || 0); }); console.log(result); // [6, 9] (123, 450)这一点与 unzip 的行为一致文档中明确写到返回数组的长度与最长的内部数组对齐较短数组中缺失的位置用undefined填充。测试用例也验证了这一行为——unzipWith的测试src/array/unzipWith.spec.ts中zip([1, 20, 300, 4000], [100, 200, 300])后再执行unzipWith由于第 4 列缺少数值结果为[4321, NaN]正是undefined参与算术运算产生的NaN。因此当输入长度不齐时应在iteratee内部做好undefined防护。空数组输入向unzipWith传入空数组会抛出错误import { unzipWith } from es-toolkit/array; const empty unzipWith([], (a, b) a b); console.log(empty); // throws Error注意这是 es-toolkit标准数组模块的行为。而在compat 兼容模块src/compat/array/unzipWith.ts中空数组以及null/undefined输入会直接返回[]而非抛错两者行为不同迁移到 compat 时需留意。compat 模块的测试也明确断言了这一点见 src/compat/array/unzipWith.spec.ts。源码实现原理标准模块unzipWith的完整实现位于 src/array/unzipWith.tsexport function unzipWithT, R(target: readonly T[][], iteratee: (...args: T[]) R): R[] { const maxLength Math.max(0, ...target.map(innerArray innerArray.length)); const result: R[] new Array(maxLength); for (let i 0; i maxLength; i) { const group new Array(target.length); for (let j 0; j target.length; j) { group[j] target[j][i]; } result[i] iteratee(...group); } return result; }实现逻辑分三步计算列数用Math.max(0, ...target.map(...))求出最长内部数组的长度作为结果数组长度Math.max(0, ...)写法确保空数组也不会得到-Infinity。按位置分组外层循环i遍历列即同一位置内层循环j遍历行即各内部数组把target[j][i]收集进group完成重排。应用转换将group展开传给iteratee(...group)结果写入result[i]。本质上等价于先unzip重排再对每组执行iteratee但一次遍历完成避免了中间数组的产生。与 unzip、zip 的协同使用unzipWith与unzip是姊妹函数unzip 只做重排把二维数组按位置重新分组返回分组后的二维数组unzipWith在重排基础上追加一层iteratee转换返回一维结果数组。二者的逆操作都是 zipzip把多个数组按索引合并为元组数组unzip/unzipWith再把它拆回并按位置聚合。测试中正是先用zip构造输入再交给unzipWith验证src/array/unzipWith.spec.ts。一个典型的组合用法是多份并列数据先用zip对齐再用unzipWith按位置逐组计算例如按列求和、求平均、拼接字符串等批量计算场景。注意事项与最佳实践标准模块 vs compat 模块行为差异标准unzipWithsrc/array/unzipWith.ts对空数组抛错compat 版本src/compat/array/unzipWith.ts对null、undefined、空数组一律返回[]且iteratee可省略省略时行为等同unzip。compat 版本还额外支持数组类似对象如{ 0: [1, 2], 1: [3, 4], length: 2 }。iteratee的参数数量iteratee会接收到一组全部元素通常参数个数应等于内部数组的个数若内部数组长度不齐末尾参数可能为undefined建议在函数内做空值兜底。不修改原数组unzipWith返回全新数组不会改动传入的target可放心在纯函数场景中使用。导入路径标准用法从es-toolkit/array导入源码导出入口见 src/array/index.ts浏览器构建的 compat 版本从src/browser.ts导出。小结unzipWith用一次简洁的调用解决了解组 转换的组合需求位置聚合交给内置逻辑具体怎么合并交给你的iteratee。无论是数值累加、字符串拼接还是对象字段聚合计算它都能与zip/unzip协同完成批量数据处理。使用前注意区分标准模块与 compat 模块在空数组、null输入和可省略iteratee上的行为差异即可安全落地到实际项目。【免费下载链接】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),仅供参考