资讯动态

D3.js d3-array 集运算详解:difference、union、intersection 与 superset、subset、disjoint 的完整用法

发布时间:2026/9/7 20:11:33 来源:尧图企业网站定制
D3.js d3-array 集运算详解difference、union、intersection 与 superset、subset、disjoint 的完整用法【免费下载链接】d3Bring data to life with SVG, Canvas and HTML. :bar_chart::chart_with_upwards_trend::tada:项目地址: https://gitcode.com/GitHub_Trending/d3/d3本文基于 D3.js 官方文档中的 Set operations 一章系统讲解 d3-array 提供的六个逻辑集运算函数——d3.difference差集、d3.union并集、d3.intersection交集、d3.superset超集判断、d3.subset子集判断和d3.disjoint不相交判断。读完本文你将掌握这些函数的签名、返回值语义与取值顺序规则理解其返回类型InternSet与普通Set的差异并能在数据清洗、用户群差异分析等实际场景中直接用任意可迭代对象完成集合逻辑运算。六个集运算函数总览d3-array 将集合逻辑运算抽象为对任意可迭代对象any iterable操作的一组函数这是该章节的原始定位Logical set operations for any iterable.。六个函数分为两类函数签名返回值用途d3.differencedifference(*iterable*, ...*others*)InternSet差集iterable中不在任何others里的值d3.unionunion(...*iterables*)InternSet并集所有iterables中出现的去重后的全部值d3.intersectionintersection(...*iterables*)InternSet交集在所有iterables中都出现的去重后的值d3.supersetsuperset(*a*, *b*)booleana是否包含b的全部值a是b的超集d3.subsetsubset(*a*, *b*)booleana的每个值是否都在b中a是b的子集d3.disjointdisjoint(*a*, *b*)booleana与b是否没有任何共享值这组函数通过本仓库的 src/index.js 以export * from d3-array的形式整体重导出因此在安装d3包后直接d3.union(...)等调用即可从 package.json 可以看到当前 d3 版本为 7.9.0依赖d3-array: ^3.2.4集运算函数属于该依赖包的 API 面。完整索引还可参考 docs/api.md 中 Sets 一节。d3.difference计算差集d3.difference(*iterable*, ...*others*)接收一个基集iterable和任意数量的其他可迭代对象others返回一个新的InternSet其中包含iterable中不存在于任何others的每一个值。官方文档给出的示例d3.difference([0, 1, 2, 0], [1]) // Set {0, 2}基集中虽然0出现了两次但返回结果只保留一份1因为在第二个参数[1]中出现而被剔除。典型场景是排除已处理的记录给定一批全部用户 ID 和一个黑名单d3.difference(allIds, blacklist)就是需要保留的用户集合。由于第二个及之后的参数是变参...*others也可以同时排除多个来源// 从候选集中排除 A、B 两个来源的值 const candidates d3.difference([10, 20, 30, 40], [20], [40, 50]); // Set {10, 30}d3.union计算并集d3.union(...*iterables*)对任意多个可迭代对象求并集返回的InternSet包含在所有给定iterables中出现过的每一个去重后的值。一个关键规则是结果集中值的顺序基于它们在给定iterables中首次出现的先后order based on first occurrence。官方文档示例d3.union([0, 2, 1, 0], [1, 3]) // Set {0, 2, 1, 3}注意结果的顺序{0, 2, 1, 3}不是数值升序而是按照0、2、1来自第一个数组的首次出现顺序随后补上仅在第二个数组中首次出现的3。这意味着并集结果保留了原始数据的出现次序而非排序后的次序这在需要保持记录原始顺序如时间序列中的事件 ID时是有意义的。// 合并多张表中的字段名保持首次出现顺序 const fields d3.union([id, name], [name, email, id]); // Set {id, name, email}d3.intersection计算交集d3.intersection(...*iterables*)返回一个InternSet包含在所有给定iterables中都出现的每一个去重后的值同样地结果顺序基于首次出现顺序。官方文档示例d3.intersection([0, 2, 1, 0], [1, 3]) // Set {1}只有1同时出现在两个数组中因此交集为{1}。交集常用于找出多个数据源的公共键例如多张 CSV 记录共同的站点 IDconst common d3.intersection(sitesA, sitesB, sitesC); // 三张表都出现的站点与并集不同如果某个值只出现在部分输入中它就会被排除变参形式允许对两个以上集合求交。superset、subset 与 disjoint布尔判断与前三者返回集合不同剩余三个函数只做判断返回布尔值d3.superset(*a*, *b*)当a是b的超集时返回true即b中的每个值也都在a中。d3.superset([0, 2, 1, 3, 0], [1, 3]) // trued3.subset(*a*, *b*)当a是b的子集时返回true即a中的每个值也都在b中。注意它与superset互为参数位置上的对偶d3.subset(x, y)等价于d3.superset(y, x)。d3.subset([1, 3], [0, 2, 1, 3, 0]) // trued3.disjoint(*a*, *b*)当a与b不相交disjoint时返回true即两个集合没有任何共享值。d3.disjoint([1, 3], [2, 4]) // true这三个判断函数接受的是给定可迭代对象内部按值相等性比较disjoint尤其适合做两个筛选条件是否互斥的快速校验而不必实际计算交集再检查是否为空。返回值类型 InternSet为何不是原生 Setdifference、union、intersection的返回值被文档明确标注为 InternSet这是 d3 对原生Set的扩展InternSet/InternMap分别继承自原生Set/Map其核心能力是绕过 SameValueZero 相等性算法允许以Date等非原始值non-primitive values作为集合元素。原生Set使用同一引用或 SameValueZero 判定重复而InternSet在判断相等时会对非原始值调用key函数默认为object.valueOf。因此在 docs/d3-array/intern.md 中演示的按日期去重场景里两个内容相同的Date对象会被视为同一个值const dates new d3.InternSet([ new Date(2022-01-01), new Date(2022-01-01) // 视为同一个值集合中仅保留一个 ]);这直接影响集运算的正确性如果你用原生Set对包含Date的对象数组求union或difference两个值相同但引用不同的日期会被当作两个元素而 d3 的集运算函数统一返回InternSet恰好规避了这个问题。文档同时指出d3.group、d3.rollup和d3.index内部也是用InternMap而非原生Map即 d3 在按值分组/集合化这条主线上对非原始值是一致地做了内省化interning处理。实战在数据管道中做差异分析与覆盖校验结合上述函数一个常见的数据管道片段是从数据源 A 中筛出新增项、校验配置覆盖、并检查两组 ID 是否冲突。由于输入可以是任意可迭代对象数组、Set、迭代器均可这些运算可以无缝嵌入已有的 d3 数据处理流import * as d3 from d3; const lastWeek [101, 102, 103]; const thisWeek [102, 103, 104]; // 本周新增的用户差集 const newUsers d3.difference(thisWeek, lastWeek); // Set {104} // 本周流失的用户反方向差集 const lostUsers d3.difference(lastWeek, thisWeek); // Set {101} // 持续存在的用户交集 const retained d3.intersection(thisWeek, lastWeek); // Set {102, 103} // 校验本周名单是否为上周名单的超集是否有用户流失 const noLoss d3.superset(thisWeek, lastWeek); // false // 校验两个渠道的 ID 是否完全互斥无重复投放 const exclusive d3.disjoint(channelA, channelB); // true / false上面的语义均可由本文列出的官方示例直接推出d3.difference([0, 1, 2, 0], [1])得到Set {0, 2}d3.superset([0, 2, 1, 3, 0], [1, 3])得到true等。使用时的两点注意一是结果顺序遵循首次出现顺序而非排序需要有序输出时请自行d3.sort([...set])二是这些函数只按值的内省化相等性比较对NaN等特殊值以及对象结构嵌套对象不会被深度比较的处理仍取决于valueOf的默认行为若需自定义相等规则应转向带key函数的 InternSet 构造方式自行组织集合。环境说明与延伸阅读适用前提安装 d3 7.x本仓库为 7.9.0及其依赖d3-array ^3.2.4后六个函数即可通过全局d3命名空间调用仓库入口 src/index.js 逐模块export *因此也适合按模块按需引入d3-array。本文所有函数签名与示例均取自 docs/d3-array/sets.md返回类型与相等性规则参见 docs/d3-array/intern.mdd3-array 各主题入口见 docs/d3-array.md。各函数在上游 d3-array 包中的源码位置difference.js、union.js、intersection.js、superset.js、subset.js、disjoint.js由官方文档给出可对照上游仓库验证实现细节。【免费下载链接】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),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价