巧妙利用引用,將陣列轉換成樹形陣列

2022-03-12 16:36:08 字數 2610 閱讀 1783

筆者所做的乙個專案需要做乙個前端的樹形選單,後端返回的資料是乙個平行的list,list中的每個元素都是乙個物件,例如list[0]的值為,每個元素都指定了父元素,生成的選單可以無限級巢狀。一開始找的外掛程式需要手動將生成好的樹形陣列傳進去才能使用(儘管後來找到了乙個ui框架,可以直接傳list進去,只需要指定id和fid),但是當時思索了好久都沒能正確寫出來,故在空下來的時候認真想了一下,整理成筆記,以便後期查閱。

因為是前端處理,所以本文實現語言為js。

如下,有乙個平行的list列表和乙個不在list中的根節點root:

var s = [

, ,

, ,

, ,

, ,

, ,

, ,

, ]var root = ;

需要乙個打亂list順序的shuffle演算法,該演算法會對原陣列進行影響:

function shuffle(a) 

};

使用json序列化來實現陣列的深度拷貝:

function deepcopy(arr)
使用乙個簡單的方式來初步判斷結果是否正確:

function check(node)
【思路】

對於這種問題,因為不知道到底要迴圈多少層,所以使用遞迴能夠以一種很方便的方式來解決。

【步驟】

1. 遍歷當前列表,找出fid為傳入的父元素的id的節點,並掛到父元素的node上;

2. 每找到乙個節點就從當前列表刪除這個元素(不然遞迴怎麼終止);

3. 對於每乙個子節點,重複如上步驟,將子節點當成下一層的父節點繼續查詢該節點的子節點。

可以看到,時間複雜度最壞為o(n!)

【實現】

function arr2tree(arr, father) 

var son = arr[i];

father.node.push(son);

arr.splice(i, 1); // 刪除該節點,當list為空的時候就終止遞迴

i--; // 由於刪除了i節點,所以下次訪問的元素下標應該還是i

}} // 再對每乙個子節點進行如上操作

if (father.node) )

}}

【檢驗】

shuffle(s); // 打亂陣列

var arr = deepcopy(s); // 拷貝乙份,避免對原陣列進行修改

arr2tree(arr, root);

console.log(check(root)); // 預期輸出15

console.log(root); // 手工檢查輸出是否正確

【思路】

當資料量大的時候,使用遞迴及其容易因為記憶體溢位而無法執行,有沒有不使用遞迴的方式呢?能不能夠直接就用迴圈來搞定呢?能不能邊遍歷這個元素,就直接把這個元素放到正確的位置上,這樣就可以省好多事情。可以用乙個雜湊表(字典/物件)來儲存這些元素,鍵(屬性名)就是元素的id,這樣就可以直接判斷當前遍歷的元素的父元素在不在雜湊表裡面了。

忽然,筆者想到了乙個特性——引用js中的物件都是引用的,哪怕我已經把a物件push進乙個list中了,我在後面對a物件進行的任何修改都會在list中反映出來。也就是說,我把a元素掛到對應的父元素f上了,當我在後面找到a元素的子元素b時,我把該子元素b掛到a上,f中掛載的a也會一樣有b元素。

【步驟】

1. 新建乙個物件temp用於存放臨時資訊。遍歷列表,將當前訪問元素a加到temp中(屬性名為物件id,屬性值為該物件);

2. 在temp中查詢是否有a的子節點,有的話就將子節點掛到a上;

3. 在temp中查詢是否有a的父節點,有的話就將a掛到父節點上;

可以看到,時間複雜度為o(n2),空間複雜度也不會太高,該方法不會對原陣列進行修改。

【實現】

function arr2tree2(arr, root) ;

temp[root.id] = root;

for (var i = 0; i < arr.length; i++)

}// 查詢是否有父節點

if (temp[arr[i].fid])

} return temp;

}

【檢驗】

shuffle(s); // 打亂陣列

var result = arr2tree2(s, root);

console.log(check(result[root.id])); // 預期輸出15

console.log(result[root.id]); // 手工檢查輸出是否正確

巧妙利用引用,將陣列轉換成樹形陣列

筆者所做的乙個專案需要做乙個前端的樹形選單,後端返回的資料是乙個平行的list,list中的每個元素都是乙個物件,例如list 0 的值為,每個元素都指定了父元素,生成的選單可以無限級巢狀。一開始找的外掛程式需要手動將生成好的樹形陣列傳進去才能使用 儘管後來找到了乙個ui框架,可以直接傳list進去...

將陣列轉換成字串

toarray 摘要 從 system.collections.generic.ienumerable建立乙個陣列。引數 source 要從其建立陣列的 system.collections.generic.ienumerable。型別引數 tsource source 中的元素的型別。返回結果 乙...

Python下將陣列 矩陣轉換成Image類

先說明一下為什麼要將陣列轉換成image類。我處理的影象是fits flexible image transport system 檔案,是一種灰度影象檔案,也就是單通道影象。fits影象的特點是灰度值取值為0 65535,這類影象在python下讀成陣列首先是不能直接轉換成位圖,也就不能用open...