JavaScript將具有父子關係的未經處理資料格式化成樹形結構資料

來源:互聯網
上載者:User

前幾天遇到一個樹型組件(類似樹形菜單)資料格式化的問題,由於後台把原始查詢的資料直接返回給前端,父子關係並未構建,因此需要前端JS來完成,後台返回的資料和下面的測試資料相似。

var data=[{id:1,pid:0,text:'A'},{id:2,pid:4,text:"E[父C]"},{id:3,pid:7,text:"G[父F]"},{id:4,pid:1,text:"C[父A]"},{id:5,pid:6,text:"D[父B]"},{id:6,pid:0,text:'B'},{id:7,pid:4,text:"F[父C]"}];

我們可以發現上面的測試資料有幾個特點,父節點與子節點不是順序排列的,也就是說按照id的順序,並不是先有父節點,然後有下面的子節點,順序是混亂的,再就是父子層級有很多,這裡是3層。總結為:順序混亂,層級未知。

如果是順序排列,層級固定,可以投機取巧,寫法相對簡單,但是這裡恰恰相反。因此給格式化造成了一定的困難,當遇到層級未知的時候,一般都會想到遞迴的寫法,這裡我感覺用遞迴也不好做,因此我也就沒有向這方面去深入思考,這裡就也不做多的說明。

那麼我的做法比起遞迴來講更容易理解,先看下代碼。

function toTreeData(data){var pos={};var tree=[];var i=0;while(data.length!=0){if(data[i].pid==0){tree.push({id:data[i].id,text:data[i].text,children:[]});pos[data[i].id]=[tree.length-1];data.splice(i,1);i--;}else{var posArr=pos[data[i].pid];if(posArr!=undefined){var obj=tree[posArr[0]];for(var j=1;j<posArr.length;j++){obj=obj.children[posArr[j]];}obj.children.push({id:data[i].id,text:data[i].text,children:[]});pos[data[i].id]=posArr.concat([obj.children.length-1]);data.splice(i,1);i--;}}i++;if(i>data.length-1){i=0;}}return tree;}

前面的測試資料經過上面代碼中的方法格式化後如下:

[    {        "id": 1,        "text": "A",        "children": [            {                "id": 4,                "text": "C[父A]",                "children": [                    {                        "id": 7,                        "text": "F[父C]",                        "children": [                            {                                "id": 3,                                "text": "G[父F]",                                "children": []                            }                        ]                    },                    {                        "id": 2,                        "text": "E[父C]",                        "children": []                    }                ]            }        ]    },    {        "id": 6,        "text": "B",        "children": [            {                "id": 5,                "text": "D[父B]",                "children": []            }        ]    }]

原理很簡單,使用一個死迴圈來遍曆數組,迴圈跳出的條件是數組的長度為0,也就是說,迴圈內部會引起數組長度的改變。這裡就幾個關鍵點做一下說明。 為什麼要用死迴圈。順序混亂,如果單次迴圈,子節點出現在父節點之前,子節點不好處理,這裡做一個死迴圈相當於先把父節點全部找出,但是這裡又不是簡單的先把所有的父節點找出,找的同時,如果這個節點父節點已經找到,那麼可以繼續做後續操作; 如何建立層級關係。代碼中有一個變數pos,這個用於儲存每個已添加到tree中的節點在tree中位置資訊,比如上面測試資料父節點A添加到tree後,那麼pos中增加一條資料,pos={”1“:[0]},1就是父節點A的id,這樣寫便於尋找,[0]表示父節點A在tree的第一個元素,即tree[0],如果某個位置資訊為[1,2,3],那麼表示這個節點在tree[1].children[2].children[3],這裡的位置關係其實就是父子的層級關係。

上面的測試資料的pos資訊如下:

{"1":[0],"2":[0,0,1],"3":[0,0,0,0],"4":[0,0],"5":[1,0],"6":[1],"7":[0,0,0]}
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.