javascript 节点排序 2


Posted in Javascript onJanuary 31, 2011
//灵感来自 
//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; 
} 
}
Javascript 相关文章推荐
JavaScript 新手24条实用建议[TUTS+]
Jun 21 Javascript
让ie6也支持websocket采用flash封装实现
Feb 18 Javascript
使用js判断当前时区TimeZone是否是夏令时
Feb 23 Javascript
关于img的href和src取变量及赋值的方法
Apr 28 Javascript
JavaScript中的this关键字使用详解
Aug 14 Javascript
利用jQuery实现WordPress中@的ID悬浮显示评论内容
Dec 11 Javascript
JS瀑布流实现方法实例分析
Dec 19 Javascript
Vue computed计算属性的使用方法
Jul 14 Javascript
React Native 环境搭建的教程
Aug 19 Javascript
快速解决Vue项目在IE浏览器中显示空白的问题
Sep 04 Javascript
详解element-ui日期时间选择器的日期格式化问题
Apr 08 Javascript
Vue form表单动态添加组件实战案例
Sep 02 Javascript
js自定义事件代码说明
Jan 31 #Javascript
jQuery帮助之筛选查找 children([expr])
Jan 31 #Javascript
jQuery find和children方法使用
Jan 31 #Javascript
与jquery serializeArray()一起使用的函数,主要来方便提交表单
Jan 31 #Javascript
基于jQuery实现表格数据的动态添加与统计的代码
Jan 31 #Javascript
jquery键盘事件介绍
Jan 31 #Javascript
javascript代码加载优化方法
Jan 30 #Javascript
You might like
通过缓存数据库结果提高PHP性能的原理介绍
2012/09/05 PHP
php合并数组中相同元素的方法
2014/11/13 PHP
Thinkphp3.2.3分页使用实例解析
2016/07/28 PHP
php正则判断是否为合法身份证号的方法
2017/03/16 PHP
PHP封装请求类实例分析【基于Yii框架】
2019/10/17 PHP
原生javascript获取元素样式属性值的方法
2010/12/25 Javascript
ie下jquery.getJSON的缓存问题的处理方法
2013/03/29 Javascript
当前页禁止复制粘贴截屏代码小集
2013/07/24 Javascript
Jquery 数组操作大全个人总结
2013/11/13 Javascript
详解AngularJS中自定义指令的使用
2015/06/17 Javascript
Vue2递归组件实现树形菜单
2017/04/10 Javascript
angular+webpack2实战例子
2017/05/23 Javascript
javascript原生封装一个淡入淡出效果的函数测试实例代码
2018/03/19 Javascript
中高级前端必须了解的JS中的内存管理(推荐)
2019/07/04 Javascript
javascript实现贪吃蛇小练习
2020/07/05 Javascript
小程序实现可拖动的悬浮按钮
2020/09/07 Javascript
如何使用gpu.js改善JavaScript的性能
2020/12/01 Javascript
[50:44]DOTA2-DPC中国联赛 正赛 SAG vs Dragon BO3 第二场 2月22日
2021/03/11 DOTA
Python浅拷贝与深拷贝用法实例
2015/05/09 Python
Python中强大的命令行库click入门教程
2016/12/26 Python
Python打印“菱形”星号代码方法
2018/02/05 Python
pandas条件组合筛选和按范围筛选的示例代码
2019/08/26 Python
tensorflow之获取tensor的shape作为max_pool的ksize实例
2020/01/04 Python
Python实现清理微信僵尸粉功能示例【基于itchat模块】
2020/05/29 Python
Python实现石头剪刀布游戏
2021/01/20 Python
全球最大最受欢迎的旅游社区:Tripadvisor
2017/11/03 全球购物
小学教师学期末自我评价
2013/09/25 职场文书
应用艺术毕业生的自我评价
2013/12/04 职场文书
2014年端午节活动方案
2014/03/11 职场文书
小学生读书活动总结
2014/06/30 职场文书
大学毕业生推荐信
2014/07/09 职场文书
竞选班干部演讲稿100字
2014/08/20 职场文书
医生爱岗敬业演讲稿
2014/08/26 职场文书
2015年新农村建设工作总结
2015/05/22 职场文书
简历上的自我评价,该怎么写呢?
2019/06/13 职场文书
MySQL为id选择合适的数据类型
2021/06/07 MySQL