节点排序 2
对支持sourceIndex的HTML文档的节点重排,使用JK提供的思路,速度至少比单纯使用nodes.sort(function(a,b){return a.sourceIndex - b.sourceIndex})这种方式快两倍:
//灵感来自 //http://www.cnblogs.com/jkisjk/archive/2011/01/28/array_quickly_sortby.html var hasDuplicate = false ; var sortBy = function (nodes){ var result = [], array = [], n = nodes.length, i = n, node; while (node = nodes[--n]){ (array[n] = new Number(~~node.sourceIndex))._ = node; } array.sort( function (a,b){ if (a === b) hasDuplicate = true ; return a - b ; }); while ( i ) result[--i] = array[i]._; return result; } |
但标准浏览器不支持这属性,在IE中,XML文档也没有此属性,这时就需要跟据节点的parentNode与nextSibling,但如果单单是两两比较,速度是提升不了的。因此我们就转而比较最近公共祖先的孩子们的顺序了。这时,算法的威力就体现出来了。这是第一版,根据某一朋友提供的LCA搞出来的东西,当然大体思路还是归功于JK大神。但实际效果不如意,比jQuery的那个sortOrder慢,估计问题出在求LCA上。
//根据这里JK提供的思路 //http://www.cnblogs.com/rubylouvre/archive/2011/01/28/1947286.html#2020900 var tick = 0, hasDuplicate = false ; var Rage = { //form http://www.cnblogs.com/GrayZhang/archive/2010/12/29/find-closest-common-parent.html getLCA: function (nodes){ var hash = {}, i = 0, attr = "data-find" +(++tick), length = nodes.length, node, parent, counter = 0, uuid; while (node = nodes[i++]){ parent = node; while (parent){ if (parent.nodeType === 1){ break ; } uuid = parent.getAttribute(attr); if (!uuid){ uuid = "_" + (++counter); parent.setAttribute(attr,uuid); hash[uuid] = {node:parent,count:1}; } else { hash[uuid].count ++; } parent = parent.parentNode; } } for ( var i in hash){ if (hash[i].count === length){ return hash[i].node; } } }, getList : function (nodes,parent){ //获取当前元素到最近公共祖先间的所有祖先,包括自己 var list = []; while (node){ if (node === parent){ break ; } list.unshift(node); node = node.parentNode; } return list; }, getLists : function (){ var lists = [], getList = Rage.getList, i=0, node, list; while (node = nodes[i++]){ list = getList(node,parent); if (list.length){ lists[ lists.length ] = list; } } return lists; }, sortList : function (a,b){ var n = Math.min(a.length,b.length),ap,bp; for ( var i=0; i < n; i++){ ap = a[i],bp = b[i] if (ap !== bp){ while (ap = ap.nextSibling){ if (ap === bp){ return -1 } } return 1 } } return a.length-b.length; }, uniqueSort : function (nodes){ var length = nodes.length; var LCA = Rage.getLCA(nodes); var lists = Rage.getLists(nodes,LCA); lists.sort(Rage.sortList); var list, i = 0, result = []; while (list = lists[i++]){ result[result.length] list.pop(); } if (result.length !== length){ result.unshift(LAC); if (result.length != length){ hasDuplicate = true ; } } return result; } } |
下面是第二版,经过改进,终于比jQuery的那个快上三倍(测试对象为拥有260多个节点的文档)
var hasDuplicate = false ; var Rage = { getList : function (node){ var list = []; while (node){ if (node.nodeType === 9){ break ; } list.unshift(node); node = node.parentNode; } return list; }, getLists : function (nodes){ var lists = [], getList = Rage.getList, i=0, node; while (node = nodes[i++]){ lists[ lists.length ] = getList(node); } return lists; }, sliceList : function (lists,num){ var result = [], i = 0, list; while (list = lists[i++]){ list = list.slice(num); if (list.length){ result[ result.length ] = list; } } return result; }, sortList : function (a,b){ var n = Math.min(a.length,b.length),ap,bp; for ( var i=0; i < n; i++){ ap = a[i],bp = b[i] if (ap !== bp){ while (ap = ap.nextSibling){ if (ap === bp){ return -1 } } return 1 } } return a.length-b.length; }, uniqueSort : function (nodes){ var length = nodes.length; var lists = Rage.getLists(nodes); lists.sort( function (a,b){ return a.length - b.length; }); var depth = lists[0].length, length = lists.length, parent, cut, ii = 0; for ( var i =0; i < depth; i++){ parent = lists[0][i]; cut = true ; for ( var j = 1;j < length; j++){ if (parent !== lists[j][i]){ cut = false ; break ; } } if (cut){ ii++ } else { break ; } } var LCA = lists[0][ii-1]; lists = Rage.sliceList(lists,ii); lists.sort(Rage.sortList); var list, i = 0, result = []; while (list = lists[i++]){ result[result.length] = list.pop(); } if (result.length !== length){ result.unshift(LCA); if (result.length != length){ hasDuplicate = true ; } } return result; } } |
如果您觉得此文有帮助,可以打赏点钱给我支付宝1669866773@qq.com ,或扫描二维码


机器瞎学/数据掩埋/模式混淆/人工智障/深度遗忘/神经掉线/计算机幻觉/专注单身二十五年
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· SQL Server 2025 AI相关能力初探
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
2010-01-30 Ext的DomQuery学习笔记