JS實現樹形結構、一維數組以及map之間的轉換

const treeData=[
{id:1,
name:'中國',
children:[
{id:11,name:'河南省',children:[{id:111,name:'南陽市',children:[{id:1111,name:'淅川縣',children:null}]},{id:112,name:'鄭州市',children:[{id:1121,name:'中牟縣',children:null}]}]
},
{id:22,name:'廣東省',children:[{id:221,name:'深圳市',children:[{id:2211,name:'寶安區',children:null},{id:2212,name:'福田區',children:null}]},{id:222,name:'廣州市',children:[{id:2221,name:'天河區',children:null},{id:2222,name:'南沙區',children:null}]}]
}]}
]
const listData1=[
{id:1,name:'中國'},
{id:11,name:'河南省',pid:1},
{id:111,name:'南陽市',pid:11},
{id:1111,name:'淅川縣',pid:111},
{id:112,name:'鄭州市',pid:11},
{id:1121,name:'中牟縣',pid:112},
{id:12,name:'廣東省',pid:1},
{id:121,name:'深圳市',pid:12},
{id:1211,name:'寶安區',pid:121},
{id:1212,name:'福田區',pid:121},
{id:122,name:'廣州市',pid:12},
{id:1221,name:'天河區',pid:122},
{id:1222,name:'南沙區',pid:122},
]

1、一維數組轉樹形結構

1.1、遞歸

//一維數組轉樹形結構
function listToTree(list){const tree=[]for(const node of list){//如果是父節點if(!node.pid){let p={...node}p.children=getChildren(p.id,list)tree.push(p)}}return tree
}
function getChildren(id,list){const children=[]//遍歷數組的每一個元素,如果找到元素的父元素節點等于當前節點,則向children中添加該元素for(const node of list){if(node.pid===id){children.push(node)}}//遍歷每一個孩子節點,遞歸尋找孩子的孩子節點,如果存在children,則向node的children中添加for(const node of children){const children=getChildren(node.id,list)if(children.length){node.children=children}}return children
}

demo:

console.log(listToTree(listData))

打印后的結果和treeData一致。

1.2、雙層循環

// 雙層循環:找出每一個元素的父節點,向每一個父節點增加children屬性
function listToTree2(list){list.forEach(child=>{const pid=child.pid//遍歷子節點,然后遍歷每一個list節點,從中找出父節點,向父節點增加孩子元素if(pid){list.forEach(parent=>{if(parent.id===pid){//如果找到的父節點還沒有孩子,會默認為空數組,否則為原來的子節點數組                    parent.children=parent.children||[]parent.children.push(child)}})}})
}

結果同1.1

1.3、使用map

//Map
function listToListMap(list){const [map,treeData]=[{},[]]//將map轉為以id為key,索引為value的對象//將數組中每個元素的children初始化為空數組for(let i=0;i<list.length;i++){map[list[i].id]=i;list[i].children=[]}console.log(map)for(let i=0;i<list.length;i++){const node=list[i]//如果是子元素并且子元素的父節點存在在list中,則找到父元素并向父元素的children中加入子元素if(node.pid&&list[map[node.pid]]){list[map[node.pid]].children.push(node)}else{//說明不是子元素,是父元素直接放入treeData中treeData.push(node)}}return treeData
}

2、tree轉list

樹形結構轉數組涉及到樹的遍歷,樹的遍歷分為深度遍歷(前中后序)和廣度遍歷。

2.1、廣度遍歷

const treeData3=[
{id:1,
name:'中國',
children:[
{id:11,name:'河南省',children:[{id:111,name:'南陽市',pid:11,children:[{id:1111,name:'淅川縣',children:null,pid:111,}]},{id:112,name:'鄭州市',pid:11,children:[{id:1121,pid:112,name:'中牟縣',children:null}]}]
},
{id:22,name:'廣東省',children:[{id:221,pid:22,name:'深圳市',children:[{id:2211,pid:221,name:'寶安區',children:null},{id:2212,pid:221,name:'福田區',children:null}]},{id:222,pid:22,name:'廣州市',children:[{id:2221,pid:222,name:'天河區',children:null},{id:2222,pid:222,name:'南沙區',children:null}]}]
}]}
]
//廣度遍歷(一層一層遍歷)
function treeToList(treeData){const list=[]const queue=[...treeData]while(queue.length){//取隊頭元素         const node=queue.shift()const children=node.children//將隊頭元素的孩子依次放入隊列中便于后序遍歷if(children){queue.push(...children)}//放入元素節點list.push(node)}return list
}
console.log(treeToList(treeData3))

打印結果同1中的listData

2.2、深度遍歷

//深度遍歷(采用棧)
function treeToList2(tree){const list=[]const stack=[...tree]while(stack.length){const node=stack.pop()//如果出棧的節點有孩子元素,那么將出棧元素的所有孩子元素都放入棧中,便于后續遍歷.const children=node.childrenif(children){stack.push(...children)}list.push(node)}return list
}

3、list轉Map(map是以父節點id為key,所有子節點作為數組為value的數據結構)

const listData4=[
{id:1,name:'中國'},//0
{id:11,name:'河南省',pid:1},//1
{id:111,name:'南陽市',pid:11},//2
{id:1111,name:'淅川縣',pid:111},//3
{id:112,name:'鄭州市',pid:11},//4
{id:1121,name:'中牟縣',pid:112},//5
{id:12,name:'廣東省',pid:1},//6
{id:121,name:'深圳市',pid:12},//7
{id:1211,name:'寶安區',pid:121},//8
{id:1212,name:'福田區',pid:121},//9
{id:122,name:'廣州市',pid:12},//10
{id:1221,name:'天河區',pid:122},//11
{id:1222,name:'南沙區',pid:122},//12
]
// 將列表數據轉為以父節點id為key,子節點為value的map
function listToMap(list){const map={}list.forEach(item=>{for(let i=0;i<list.length;i++){//如果外層循環元素的id等于內層循環元素的pid,說明內層元素是外層元素的子元素,則向map的value中添加該內層元素.if(list[i].pid===item.id){map[item.id]=map[item.id]||[]map[item.id].push(list[i])}}})return map
}
console.log(listToMap(listData4))

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/37818.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/37818.shtml
英文地址,請注明出處:http://en.pswp.cn/news/37818.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

c++中的多態

文章目錄 1.多態的概念1.1概念 2.多態的定義及實現2.1多態的構成條件2.2虛函數2.3虛函數的重寫2.4 C11 override 和 final2.5 重載、覆蓋(重寫)、隱藏(重定義)的對比 3. 抽象類3.1概念3.2接口繼承和實現繼承 4.多態的原理4.1虛函數表4.2多態原理分析4.3 動態綁定與靜態綁定 5.單…

學習筆記整理-面向對象-03-構造函數

一、構造函數 1. 用new調用函數的四步走 new 函數();JS規定&#xff0c;使用new操作符調用函數會進行"四步走"&#xff1a; 函數體內會自動創建出一個空白對象函數的上下文(this)會指向這個對象函數體內的語句會執行函數會自動返回上下文對象&#xff0c;即使函數沒…

HDMI接口的PCB布局布線要求

高清多媒體接口&#xff08;High Definition Multimedia Interface&#xff09;&#xff0c;簡稱&#xff1a;HDMI&#xff0c;是一種全數字化視頻和聲音發送接口&#xff0c;可以發送未壓縮的音頻及視頻信號。隨著技術的不斷提升&#xff0c;HDMI的傳輸速率也不斷的提升&#…

使用GEWE框架進行微信群組管理(三)

友情鏈接&#xff1a;GEWE框架官網 geweapi.com 點擊訪問即可。 邀請或添加聯系人進群 小提示&#xff1a; 不管是添加40人以內還是以上都用此接口cause填寫邀請進群的理由 請求URL&#xff1a; http://域名地址/api/group/invite 請求方式&#xff1a; POST 請求頭&…

brew+nginx配置靜態文件服務器

背景 一下子閑下來了&#xff0c;了解的我的人都知道我閑不下來。于是&#xff0c;我在思考COS之后&#xff0c;決定自己整一個本地的OSS&#xff0c;實現靜態文件的訪問。那么&#xff0c;首屈一指的就是我很熟的nginx。也算是個小復習吧&#xff0c;復習一下nginx代理靜態文…

解決生成式AI落地之困,亞馬遜云科技提供完整解決方案

生成式AI技術無疑是當前最大的時代想象力之一。 資本、創業者、普通人都在涌入生成式AI里去一探究竟&#xff1a;“百模大戰”連夜打響&#xff0c;融資規模連創新高&#xff0c;各種消費類產品概念不斷涌現……根據Bloomberg Intelligence 的報告&#xff0c;2022年生成式AI 市…

文件操作/IO

文件 文件是一種在硬盤上存儲數據的方式&#xff0c;操作系統幫我們把硬盤的一些細節都封裝起來了&#xff0c;程序員只需要了解文件相關的接口即可&#xff0c;相當于操作文件就是間接的操作硬盤了 硬盤用來存儲數據&#xff0c;和內存相比硬盤的存儲空間更大&#xff0c;訪問…

使用FTP文件傳輸協議的潛在風險

數據&#xff08;事實&#xff0c;數字&#xff0c;價值&#xff09;是當今業務運行的核心要素。但是&#xff0c;如果數據沒有得到有效的存儲和傳輸&#xff0c;它們就會成為阻礙業務發展的障礙。如果企業不能及時地把數據送到合適的地方&#xff0c;就會造成嚴重的經濟損失。…

【skynet】skynet 入門代碼

寫在前面 本文將從零開始&#xff0c;寫第一個 skynet 程序 HelloWorld 。通過 HelloWorld 可以熟悉 skynet 的運作方式&#xff0c;和了解其 api 。 文章目錄 寫在前面準備工作編寫代碼運行結果 準備工作 首先要有一個編譯好&#xff0c;而且工作正常的 skynet 。 編寫代碼…

【Linux】Shell腳本之流程控制語句 if判斷、for循環、while循環、case循環判斷 + 實戰詳解[?建議收藏!!?]

&#x1f468;?&#x1f393;博主簡介 &#x1f3c5;云計算領域優質創作者 ??&#x1f3c5;華為云開發者社區專家博主 ??&#x1f3c5;阿里云開發者社區專家博主 &#x1f48a;交流社區&#xff1a;運維交流社區 歡迎大家的加入&#xff01; &#x1f40b; 希望大家多多支…

.bit域名調研

.bit域名研究 問題&#xff1a; .bit域名和ENS域名的相同點&#xff1f;不同點&#xff1f;有什么關系&#xff1f; .bit的定義 .bit 是基于區塊鏈的&#xff0c;開源的&#xff0c;跨鏈去中心化賬戶系統.bit 提供了以 .bit 為后綴的全局唯一的命名體系&#xff0c;可用于加密…

安全第二次

一&#xff0c;iframe <iframe>標簽用于在網頁里面嵌入其他網頁。 1&#xff0c;sandbox屬性 如果嵌入的網頁是其他網站的頁面&#xff0c;因不了解對方會執行什么操作&#xff0c;因此就存在安全風險。為了限制<iframe>的風險&#xff0c;HTML 提供了sandb…

分布式應用:Zabbix監控MariaDB

目錄 一、理論 1.Zabbix監控MariaDB 二、實驗 1.Zabbix監控MariaDB 一、理論 1.Zabbix監控MariaDB &#xff08;1&#xff09;環境 zabbix服務端&#xff1a;192.168.204.214 zabbix客戶端&#xff1a;192.168.204.215 &#xff08;2&#xff09;MareaDB安裝 安裝 za…

做海外游戲推廣有哪些條件?

做海外游戲推廣需要充分準備和一系列條件的支持。以下是一些關鍵條件&#xff1a; 市場調研和策略制定&#xff1a;了解目標市場的文化、玩家偏好、競爭格局等是必要的。根據調研結果制定適合的推廣策略。 本地化&#xff1a;將游戲內容、界面、語言、貨幣等進行本地化&#…

使用ip2region獲取客戶端地區

目錄 從gitee拉取ip2region.xdb資源文件 寫測試類 注意要寫對資源路徑 本地測試結果 ?編輯 遠端測試結果 從gitee拉取ip2region.xdb資源文件 git clone https://gitee.com/lionsoul/ip2region.git 將xdb放入resources資源文件夾 引入依賴 <dependency><groupId&…

由淺入深C系列五:使用libcurl進行基于http get/post模式的C語言交互應用開發

使用libcurl進行基于http get/post模式的C語言交互應用開發 簡介環境準備在線資源示例代碼測試調用運行結果 簡介 大多數在linux下的開發者&#xff0c;都會用到curl這個命令行工具。對于進行restful api的測試等&#xff0c;非常方便。其實&#xff0c;這個工具還提供了一個C…

Python中單引號、雙引號和三引號的區別

① 單引號和雙引號主要用來表示字符串 # 單引號 astr = Python print(type(astr)) # <class str># 雙引號"" bstr = "Python" print(type(bstr)) # <class str> str1 = I\m a big fan of Python. print(str1) # Im a big fan of Python.s…

[HDLBits] Exams/m2014 q4d

Implement the following circuit: module top_module (input clk,input in, output out);always(posedge clk) beginout<out^in;end endmodule直接寫out^in就行

Vue 使用 vite 創建項目

vite 是新一代前端構建工具&#xff0c;和 webpack 類似。 vite 的啟動速度更快。在開發環境中&#xff0c;不需要打包就可以直接運行。 vite 的更新速度更快。當修改內容后&#xff0c;不需要刷新瀏覽器&#xff0c;頁面就會實時更新。 vite 完全是按需編譯。它只會編譯需要…

【考研數學】高等數學第三模塊——積分學 | Part II 定積分(反常積分及定積分應用)

文章目錄 前言三、廣義積分3.1 斂散性概念&#xff08;一&#xff09;積分區間為無限的廣義積分&#xff08;二&#xff09;積分區間有限但存在無窮間斷點 3.2 斂散性判別法 四、定積分應用寫在最后 前言 承接前文&#xff0c;梳理完定積分的定義及性質后&#xff0c;我們進入…