尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Cytoscape.js 集合 every() 方法详解:全量条件校验与源码级剖析

Cytoscape.js 集合 every() 方法详解:全量条件校验与源码级剖析 Cytoscape.js 集合 every() 方法详解全量条件校验与源码级剖析【免费下载链接】cytoscape.jsGraph theory (network) library for visualisation and analysis项目地址: https://gitcode.com/gh_mirrors/cy/cytoscape.jsevery()是 Cytoscape.js 中集合collection对象提供的全量谓词校验方法它遍历集合中的每一个元素只有当所有元素都满足回调函数或条件时才返回true。它在图数据校验、筛选前置判断、布局/样式批量操作前的条件检查等场景中非常实用本文结合仓库源码与测试用例深入讲解其用法、回调参数、边界行为以及与some()、allAre()等兄弟方法的异同。一、核心用法与官方示例eles.every( fn )对集合eles中的每个元素依次调用回调函数fn只要有一个元素令fn返回假值false就立即返回false并停止遍历只有全部元素都返回真值最终才返回true。原文档给出了如下示例见 every.mdvar jAndE cy.$(#j, #e); var everyHeavierThan50 jAndE.every(function( ele ){ return ele.data(weight) 50; }); console.log( every heavier than 50 ? everyHeavierThan50 );这里先用选择器#j, #e通过cy.$()取回 id 分别为j和e的两个元素组成集合然后检查这两个元素的weight数据是否全部大于 50。只要其中一个元素的weight 50结果即为false。回调函数的三个参数与原生数组的Array.prototype.every一致Cytoscape.js 的回调会收到三个参数参数含义ele当前遍历到的元素node 或 edgei当前元素在集合中的索引从 0 开始eles正在遍历的整个集合对象这一点有测试用例直接验证见 collection-comparison.mjsit(eles.every(), function(){ expect( cy.edges().every(function( ele, i, eles ){ expect( is.elementOrCollection(ele) ).to.be.true; expect( is.elementOrCollection(eles) ).to.be.true; expect( is.number(i) ).to.be.true; return ele.data(source) n1; }) ).to.be.false; expect( cy.edges().every(function( ele, i, eles ){ expect( is.elementOrCollection(ele) ).to.be.true; expect( is.elementOrCollection(eles) ).to.be.true; expect( is.number(i) ).to.be.true; return ele.isEdge(); }) ).to.be.true; });该测试在beforeEach中初始化了 3 个节点n1、n2、n3和 2 条边n1n2、n2n3第一条断言因为并非所有边的source都是n1n2n3的 source 是n2所以返回false第二条断言两条边全部满足ele.isEdge()所以返回true。返回值语义所有元素都满足条件 → 返回true任意一个元素不满足条件 → 立即短路返回false空集合→ 从实现逻辑看循环体一次都不执行直接返回true数学上的全称命题对空集成立语义这是从源码结构可直接推断的行为。二、源码级实现原理every()定义在集合比较模块中见 comparators.mjsevery: function( fn, thisArg ){ for( let i 0; i this.length; i ){ let ret !thisArg ? fn( this[ i ], i, this ) : fn.apply( thisArg, [ this[ i ], i, this ] ); if( !ret ){ return false; } } return true; },关键实现细节基于下标循环Cytoscape.js 的集合对象继承了Array.prototype见 index.mjs元素通过this[i]按下标直接访问因此every()本质上就是对集合内部数组做一次线性扫描时间复杂度为 O(n)最坏情况。短路求值一旦某个元素令回调返回假值立即return false不再继续遍历适合对大型图做快速失败校验。可选的thisArg第二个参数用于绑定回调内部的this上下文。不传时直接以fn( this[i], i, this )形式调用传入时通过fn.apply( thisArg, [ this[i], i, this ] )显式指定this。回调返回值判定使用if( !ret )判断因此回调返回0、null、undefined、等任何假值时都会导致结果为false返回任意真值则继续。该模块通过util.extend( elesfn, props )挂载到集合原型见 index.mjs且由于元素Element与集合共享同一原型单个元素同样可以直接调用ele.every(...)。三、实用场景示例1. 校验图中所有节点都已定位var allPositioned cy.nodes().every(function( node ){ return node.position().x ! null node.position().y ! null; }); if( allPositioned ){ console.log(所有节点都有明确坐标可以执行布局或导出); }2. 校验边数据完整性后再运行图算法var cy window.cy; var edgesReady cy.edges().every(function( edge ){ return typeof edge.data(weight) number edge.data(weight) 0; }); if( edgesReady ){ var result cy.elements().dijkstra( { root: #n1, weight: function( ele ){ return ele.data(weight); } } ); // 继续使用最短路径结果…… }3. 与选择器结合先取子集再校验var selectedNodes cy.$(node:selected); var allSelectedLocked selectedNodes.every(function( node ){ return node.locked(); }); if( allSelectedLocked ){ console.log(所有选中节点都处于锁定状态); }四、与some()、allAre()等方法的对比在同一个 comparators.mjs 模块中还定义了语义互补的系列方法方法语义返回true的条件说明every( fn )全量满足所有元素满足fn本文主角短路于首个失败元素some( fn )存在满足至少一个元素满足fn短路于首个成功元素见 some.mdallAre( selector )全量匹配选择器所有元素都匹配选择器基于every()实现return this.every(function( ele ){ return selObj.matches( ele ); })见 comparators.mjs见 allAre.mdis( selector )存在匹配选择器至少一个元素匹配选择器基于some()实现见 comparators.mjs见 is.md从源码可以清晰地看到allAre是用选择器写法的 everyis是用选择器写法的 some。选择器版本更简洁但灵活性低于回调版本——回调可以访问元素数据ele.data()、坐标ele.position()、样式ele.style()等运行时信息而选择器只能基于既有的数据字段、类名、状态等结构化属性。典型组合用法cy.elements().every(...)判断全图cy.$(#a, #b).some(...)判断子集。例如在 collection-comparison.mjs 的allAre测试中cy.$(#n1, #n2).allAre(node)为true而cy.$(#n1, #n1n2).allAre(node)因混入了边而返回false——这与every的全量满足语义完全一致。五、注意事项与最佳实践条件函数中的return不要遗漏every()依赖回调返回值做判断回调体若漏写return会返回undefined假值导致结果恒为false。空集合返回true对cy.collection()等空集合调用every()会直接得到true在业务逻辑中若需要非空且全部满足应先判断eles.length 0或使用eles.nonempty()。避免在回调中修改集合遍历期间修改集合元素可能导致索引错位建议先用eles.filter()或eles.remove()等操作生成新集合后再校验。thisArg用法当回调是对象方法时可用eles.every( obj.check, obj )形式绑定this便于复用校验逻辑。性能every与some均具备短路特性在校验大型图时比先filter()再比长度的方式更高效因为失败时不必扫描完整个集合。结语every()是 Cytoscape.js 集合 API 中最基础也最常用的全量校验入口其实现简洁、语义清晰并与some()、allAre()、is()构成完整的谓词校验矩阵。无论是做数据完整性检查、图算法前置条件判断还是交互场景中的状态汇总它都能以可读、可维护的方式表达是否全部满足这一逻辑。更多集合方法与示例可参考 collection 文档目录 及对应的单元测试 collection-comparison.mjs。【免费下载链接】cytoscape.jsGraph theory (network) library for visualisation and analysis项目地址: https://gitcode.com/gh_mirrors/cy/cytoscape.js创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表