小强们难免会和树打交道, 一提到树, 小强们都会想到用递归. 不可否认,我也写了很多年的递归.
但是递归需要大量的循环.
这里,利用地址引用进行快速排树,只需要一次循环.
1,从儿子找父亲
这是我构造的测试数据:
1,0;2,0;3,1;4,3;5,4;6,5;7,4;8,3;9,8;10,9
儿子,父亲;儿子,父亲;儿子,父亲;.....
1 var str = "1,0;2,0;3,1;4,3;5,4;6,5;7,4;8,3;9,8;10,9"; 2 var datas = str.Split(new char[] { ‘;‘ }) 3 .Select(s => { 4 var tmp = s.Split(new char[] { ‘,‘ }); 5 return new { 6 ID = tmp[0].ToInt(), 7 PID = tmp[1].ToInt() 8 }; 9 }); 10 11 var dic = new Dictionary<decimal, Tmp>(); 12 foreach (var kv in datas) { 13 var tmp = new Tmp() { 14 ID = kv.ID, 15 PID = kv.PID 16 }; 17 18 dic.Set(kv.ID, tmp); 19 20 var parent = dic.Get(kv.PID, new Tmp() { 21 ID = kv.PID 22 }); 23 24 tmp.Parent = parent; 25 }
1 private class Tmp { 2 3 public int ID { 4 get; 5 set; 6 } 7 8 public int PID { 9 get; 10 set; 11 } 12 public Tmp Parent { 13 get; 14 set; 15 } 16 }
除构造测试数据外,只用了一次循环,没有嵌套.
ToInt 和 dic.Set 方法是自定义的扩展方法, 只做辅助,和排树没关系.
从根找儿子,没有现成的CS示例,也懒得写, 贴段用于 js treegrid 的代码:
1 var dealTree = function (tab) { 2 var rows = tab.rows; 3 var row; 4 5 var treeObjs = {}; 6 var tmp = {}; 7 8 for (var i = 0; row = rows[i]; i++) { 9 var id = $(row).attr("data-treegrid-id"); 10 var pId = $(row).attr("data-treegrid-parentID"); 11 12 if (id == undefined || pId == undefined) 13 continue; 14 15 if (!tmp[pId]) 16 tmp[pId] = {}; 17 18 if (!tmp[id]) 19 tmp[id] = { hasChild: false }; 20 21 tmp[id].pID = pId; 22 23 tmp[pId][id] = tmp[id]; 24 tmp[pId].hasChild = true; 25 } 26 27 for (var t in tmp) { 28 if (tmp[t].pID == undefined) { 29 treeObjs[t] = tmp[t]; 30 } 31 } 32 33 return treeObjs; 34 }
原理都一样.
写这个东东,主要是从网上找不到适用于直接套在 table 上的 treegrid, 要么是从 json 构造树表,要么是必须先排好行的顺序,用着都很蛋疼.我就需要一个能直接在现有 table 上自动排树的一个表格的功能而以.找了很久都没找到满意的,只能自己动手了:
1 var Treegrid = {}; 2 (function (t) { 3 4 var self = this; 5 6 var dealTree = function (tab) { 7 var rows = tab.rows; 8 var row; 9 10 var treeObjs = {}; 11 var tmp = {}; 12 13 for (var i = 0; row = rows[i]; i++) { 14 var id = $(row).attr("data-treegrid-id"); 15 var pId = $(row).attr("data-treegrid-parentID"); 16 17 if (id == undefined || pId == undefined) 18 continue; 19 20 if (!tmp[pId]) 21 tmp[pId] = {}; 22 23 if (!tmp[id]) 24 tmp[id] = { hasChild: false }; 25 26 tmp[id].pID = pId; 27 28 tmp[pId][id] = tmp[id]; 29 tmp[pId].hasChild = true; 30 } 31 32 for (var t in tmp) { 33 if (tmp[t].pID == undefined) { 34 treeObjs[t] = tmp[t]; 35 } 36 } 37 38 return treeObjs; 39 } 40 41 var getSubIds = function (treeObjs, arr) { 42 for (var t in treeObjs) { 43 if (typeof (treeObjs[t]) != "object") 44 continue; 45 46 arr.push(t); 47 48 if (treeObjs[t].hasChild) 49 getSubIds(treeObjs[t], arr); 50 } 51 return arr; 52 } 53 54 var generate = function (treeObjs, tab, tbody, level) { 55 for (var t in treeObjs) { 56 var node = treeObjs[t]; 57 58 if (typeof (node) != "object") 59 return; 60 61 var row = $(tab).find("tr[data-treegrid-id=" + t + "]"); 62 var td = row.find("td:eq(0)"); 63 var indents = new Array(level).join("<span class=‘treegridIndent‘></span>"); 64 65 var htmls = [indents]; 66 67 if (node.hasChild) { 68 var subIds = getSubIds(node, new Array()); 69 htmls.push("<span data-treegrid-subs=‘" + subIds.join(",") + "‘ class=‘glyphicon glyphicon-chevron-down‘></span>") 70 } 71 htmls.push(td.html()); 72 73 td.html(htmls.join("")); 74 tbody.append(row); 75 generate(node, tab, tbody, level + 1); 76 } 77 } 78 79 var init = function (tab) { 80 if ($(tab).attr("data-treegrid-dealed") == true) 81 return; 82 83 var treeObjs = dealTree(tab); 84 85 var tbody = $("<tbody>"); 86 87 generate(treeObjs, tab, tbody, 0); 88 $(tab).append(tbody); 89 $(tab).attr("data-treegrid-dealed", true); 90 } 91 92 $.fn.treegrid = function () { 93 this.each(function () { 94 init(this); 95 }); 96 97 $("span[data-treegrid-subs]").on("click", function () { 98 var subIds = $(this).attr("data-treegrid-subs").split(‘,‘); 99 var explanded = $(this).data("data-treegrid-expandend"); 100 explanded = explanded == undefined ? true : explanded; 101 var id; 102 for (var i = 0; id = subIds[i]; i++) { 103 var tr = $("tr[data-treegrid-id=‘" + id + "‘]"); 104 tr.toggle(!explanded); 105 } 106 $(this) 107 .data("data-treegrid-expandend", !explanded) 108 .removeClass("glyphicon-chevron-right").removeClass("glyphicon-chevron-down") 109 .addClass(explanded ? "glyphicon glyphicon-chevron-right" : "glyphicon glyphicon-chevron-down"); 110 }); 111 } 112 113 })(Treegrid);
最终效果长这样,丑是丑了点,但是简单.
谢谢围观.
利用 地址引用 进行 快速排树 的简单方法
时间: 2024-10-05 05:08:00