资讯详情

资讯详情

d3 数据变换完全指南:d3.cross、d3.merge、d3.zip 等 8 个数组派生函数详解

d3 数据变换完全指南d3.cross、d3.merge、d3.zip 等 8 个数组派生函数详解【免费下载链接】d3Bring data to life with SVG, Canvas and HTML. :bar_chart::chart_with_upwards_trend::tada:项目地址: https://gitcode.com/GitHub_Trending/d3/d3D3 的d3-array模块除排序、聚合外还提供了一组专门用于从已有数组派生新数组的变换函数d3.cross、d3.merge、d3.pairs、d3.transpose、d3.zip以及可作用于任意可迭代对象的d3.filter、d3.map、d3.reduce。本文以 docs/d3-array/transform.md 中的完整 API 说明为主体结合本仓库的模块组织与测试入口逐一讲解每个函数的签名、参数、返回行为与典型用法帮助你在数据预处理阶段生成组合、拉平嵌套、按行转置、迭代求值直接用现成函数替代手写循环。这些函数在 d3 仓库中的位置在 d3 v7 中d3主包是一个聚合包它本身不重复实现数组逻辑而是通过 src/index.js 以export * from d3-array的形式把整个 d3-array 模块的 API 平铺到d3命名空间下。package.json 声明依赖d3-array: ^3.2.4因此本文介绍的 8 个函数在 ESM 或 UMDdist/d3.min.js中均可通过d3.xxx直接调用。仓库的集成测试 test/d3-test.js 会遍历package.json中每一个依赖模块断言该模块导出的每个属性除version外都出现在d3对象中保证了d3.cross、d3.zip等符号与 d3-array 模块一一对应。官方 API 总览 docs/api.md 也将这组函数统一归入 Transform - Derive new arrays 一节与本文一一对应。从 CHANGES.md 可以看出这组 API 的设计背景D3 v2 起使用原生集合Map 和 Set并接受可迭代对象iterables。这正是本文所有函数的共同特征——它们的第一个参数几乎都是iterable而非array因此Set、Map的键值、d3.groups生成的嵌套结构都可以直接传入无需先Array.from转数组。d3.cross计算多个可迭代对象的笛卡尔积d3.cross(...iterables, reducer)返回给定各可迭代对象的笛卡尔积即所有元素组合构成的数组。d3.cross([1, 2], [x, y]) // [[1, x], [1, y], [2, x], [2, y]]从 CHANGES.md 的记录看d3.cross自 d3-array 2.x 起已允许传入两个以上的可迭代对象因此组合不限于两两配对d3.cross([1, 2], [x, y], [true, false]) // 8 个组合每个组合是长度为 3 的数组若指定了reducer它会对每个组合依次被调用返回值构成最终结果——这是把组合直接折叠为派生值如拼接键名、生成矩阵单元的最简写法d3.cross([1, 2], [x, y], (a, b) a b) // [1x, 1y, 2x, 2y]典型场景生成热力图/分组图表的 (x, y) 坐标网格、为交叉表展开所有行列表头组合都可以直接交给d3.cross而不是手写双层循环。d3.merge把可迭代对象的可迭代对象拉平为一维数组d3.merge(iterables)将一层嵌套结构合并为一个扁平数组。官方文档将其与内置Array.prototype.concat对比当你手里是数组的数组或任意可迭代对象集合时d3.merge比逐个 concat 更顺手。d3.merge([[1], [2, 3]]) // [1, 2, 3]由于接受任意可迭代对象Set的集合套集合同样适用d3.merge(new Set([new Set([1]), new Set([2, 3])])) // [1, 2, 3]实战中它最常见的来源是d3.group的分组结果按类别分组得到Map或嵌套数组后用d3.merge即可一次性取回全部原始记录无需遍历Map手动拼接。d3.pairs提取相邻元素对d3.pairs(iterable, reducer)按顺序返回相邻元素组成的二元组数组若可迭代对象不足两个元素返回空数组。d3.pairs([1, 2, 3, 4]) // [[1, 2], [2, 3], [3, 4]]d3.pairs是滑动窗口大小为 2的便捷操作常用于把时间序列、多边形顶点这类点列转换为段列——例如为每条相邻连线、每段折线各生成一个元素。若指定reducer它会依次接收前一个元素i - 1与当前元素i返回每次折叠的结果d3.pairs([1, 1, 2, 3, 5], (a, b) b - a) // [0, 1, 1, 2]上例正是计算斐波那契序列的相邻差分。需要更长窗口三元组、更长滑窗时文档给出的思路是用d3.group系列或手写窗口d3.pairs本身只负责二元相邻关系。d3.zip 与 d3.transpose列式合并与矩阵转置d3.zip按行位置把多个数组压成元组数组d3.zip(...arrays)返回一个数组其中第i个元素是由各参数数组的第i个元素组成的数组。三条边界行为值得注意均出自 docs/d3-array/transform.md 的原文定义结果长度被截断到最短数组的长度只传入单个数组时返回的是一系列单元素数组无参数时返回空数组。d3.zip([Alice, Bob, Carol], [32, 13, 14]) // [[Alice, 32], [Bob, 13], [Carol, 14]]截断行为意味着各参数数组长度不一致时多出的尾部数据会被静默丢弃——在合并 CSV 各列docs/public/data/riaa-us-revenue.csv 这类宽表数据之前应先确认各列等长否则会丢行。d3.transpose把 zip 用作二维矩阵转置d3.transpose(matrix)的文档表述是使用 zip 算子实现二维矩阵转置。对行等长的矩阵d3.transpose(matrix)等价于d3.zip(...matrix)输入输出互为转置d3.transpose([[Alice, Bob, Carol], [32, 13, 14]]) // [[Alice, 32], [Bob, 13], [Carol, 14]]d3.transpose([[Alice, 32], [Bob, 13], [Carol, 14]]) // [[Alice, Bob, Carol], [32, 13, 14]]两个例子正好互逆第一行把姓名行 年龄行的 2×3 结构转成每行一人的 3×2 结构第二行再转回原形。在需要列数据 → 行记录比如把按度量组织的表格喂给d3-shape的行列生成器时d3.transpose是最直接的桥接工具。d3.filter / d3.map / d3.reduce面向任意可迭代对象的三大函数式操作这组函数对应内置Array.prototype.filter/map/reduce区别在于接受任意可迭代对象——Set、Map的 keys/values、生成器等。d3.filter返回一个数组按顺序包含test函数返回true的那些元素d3.filter(new Set([0, 2, 3, 4]), (d) d 1) // [3]d3.map按mapper函数顺序生成映射值数组d3.map(new Set([0, 2, 3, 4]), (d) d 1) // [0, 0, 1, 0]d3.reduce以reducer反复折叠整个可迭代对象返回最终的归约值d3.reduce(new Set([0, 2, 3, 4]), (p, v) p v, 0) // 9三者的参数语义与数组原型方法保持一致回调接收当前元素、索引、容器因此已有arr.filter(fn)的写法可以近乎零成本迁移到d3.filter(iterable, fn)。它们的价值集中在两类输入其一d3.group/d3.rollup等聚合函数返回的Map可直接对其values()做d3.reduce而不用先物化为数组其二一次性的生成器或流式数据可以在不落地为数组的情况下完成筛选与求值。使用前提与注意事项版本前提本文基于当前仓库 package.json 声明的 d3 v7.9.0聚合d3-array ^3.2.4构建要求 Node12测试脚本为mocha test/**/*-test.js见 package.json 的scripts与engines字段。可迭代对象 ≠ 数组8 个函数返回的都是标准数组除d3.reduce返回归约值、d3.cross的 reducer 模式外可以继续参与d3.group、d3.scaleBand等后续管线但输入侧请区分可迭代对象与数组Set的重复值会被天然去重这会影响d3.merge等函数对输入Set的结果。zip 的截断语义d3.zip按最短数组截断且不做报错多列数据合并前请自行校验长度避免静默丢数据。与内置方法的取舍纯数组输入下Array.prototype.map/filter/reduce完全可用且性能更直接d3.filter/map/reduce的增益点在于对非数组可迭代对象的统一支持保持代码风格一致。小结docs/d3-array/transform.md 定义的这组变换函数覆盖了数据派生的四种基本形态组合d3.cross、合并d3.merge、相邻关系d3.pairs、转置d3.zip/d3.transpose再叠加可作用于任意可迭代对象的d3.filter/d3.map/d3.reduce。它们通过 src/index.js 的export * from d3-array直接进入d3命名空间并由 test/d3-test.js 的导出一致性测试兜底。在实际做图管线中把展开网格、拉平分组、行转列、折叠求值这四类步骤映射到对应函数可以省去大量手写循环也让预处理逻辑与 D3 其余模块的数据契约保持一致。【免费下载链接】d3Bring data to life with SVG, Canvas and HTML. :bar_chart::chart_with_upwards_trend::tada:项目地址: https://gitcode.com/GitHub_Trending/d3/d3创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →