JavaScript遞歸操作樹(shù)形結(jié)構(gòu)代碼示例
樹(shù)形結(jié)構(gòu)轉(zhuǎn)成扁平結(jié)構(gòu)
數(shù)據(jù)結(jié)構(gòu)
let data = [
{
name: "1",
children: [{
name: "3"
}, {
name: "4"
}]
},
{
name: "2",
children: [{
name: "5"
}, {
name: "6",
children: [{name: "7"}]
}]
}
]轉(zhuǎn)成扁平化
function dataTree(data) {
let result = [];
for (const item of data) {
// result.push(item)
result.push({ name: item.name }) // 只取當(dāng)前節(jié)點(diǎn)的信息,不包括 children
if (item.children === null || item.children === undefined) {
continue;
}
let getChildren = dataTree(item.children)
result = result.concat(getChildren)
}
return result
}
console.log("原數(shù)組結(jié)構(gòu)", data);
console.log("扁平化的對(duì)象", dataTree(data));運(yùn)行結(jié)果

扁平結(jié)構(gòu)轉(zhuǎn)成樹(shù)形結(jié)構(gòu)
數(shù)據(jù)結(jié)構(gòu)
let datas = [
{id: 1, name: 1, parentId: null},
{id: 2, name: 2, parentId: 1},
{id: 3, name: 3, parentId: 1},
{id: 4, name: 4, parentId: null},
{id: 5, name: 5, parentId: 4},
{id: 6, name: 6, parentId: 4},
{id: 7, name: 7, parentId: 6},
{id: 8, name: 8, parentId: 6},
]轉(zhuǎn)成樹(shù)形結(jié)構(gòu)
function dataList(data){
let map = {};
for(let item of data){
map[item.id] = item
}
let result = []; //存放數(shù)組
for(let item of data){
item.children = []; //給每個(gè)數(shù)組添加一個(gè)空children
if(item.parentId === null){
result.push(item)//最上級(jí)的標(biāo)簽
}else{
//相當(dāng)于用這個(gè) parentId 當(dāng)做父Id去查找對(duì)比查找數(shù)據(jù)
let parent = map[item.parentId]
//添加到剛剛定義children數(shù)組中去
parent.children.push(item)
}
}
return result;
}
console.log("扁平化轉(zhuǎn)換成樹(shù)形結(jié)構(gòu):");
console.log("原數(shù)組結(jié)構(gòu)",datas);
console.log("樹(shù)形結(jié)構(gòu)",dataList(datas));運(yùn)行結(jié)果

根據(jù) parentId 查詢對(duì)應(yīng)的上級(jí)所有父節(jié)點(diǎn)
數(shù)據(jù)結(jié)構(gòu)
const data = [
{
id: 1,
parentId: undefined,
name: 'TEST 1',
children: [
{
id: 5,
parentId:1,
name: 'TEST 5',
children: [
{
id: 10,
parentId:4,
name: 'TEST 10'
},
{
id: 11,
parentId:4,
name: 'TEST 11'
}
]
}
]
},
{
id: 2,
parentId: undefined,
name: 'TEST 2',
children: [
{
id: 6,
parentId:2,
name: 'TEST 6'
},
{
id: 7,
parentId:2,
name: 'TEST 7'
}
]
},
{
id: 3,
parentId: undefined,
name: 'TEST 3',
children: [
{
id: 8,
parentId:3,
name: 'TEST 8'
},
{
id: 9,
parentId:3,
name: 'TEST 9'
}
]
},
{
id: 4,
name: 'TEST 4',
children: [
]
}
]根據(jù)parentId查找父節(jié)點(diǎn)
/**
*
* @param list 最外層傳入的數(shù)組 也可以是 this.數(shù)組
* @param parentId 子節(jié)點(diǎn)對(duì)應(yīng)的上級(jí)關(guān)系parentId
* @returns {*[]}
*/
function findP(list,parentId){
const result = []
/**
* 處理邏輯
* @param arr 要對(duì)比的數(shù)組
* @param parentId 傳遞進(jìn)來(lái)數(shù)據(jù)要對(duì)比父id(相當(dāng)于parentId)
*/
let forFn = function (arr,parentId){
for (let i = 0; i < arr.length; i++) {
let item = arr[i];
if (item.id === parentId){
result.push(item)
// console.log("遞歸數(shù)據(jù)",item)
// console.log("遞歸id",item.parentId)
forFn(list,item.parentId)
break
}else {
if (item.children){
forFn(item.children,parentId)
}
}
}
}
forFn(list,parentId);
return result;
}
console.log("數(shù)據(jù)結(jié)構(gòu)==",data)
console.log("查詢父類==",findP(data,11))運(yùn)行結(jié)果(會(huì)把自己及父節(jié)點(diǎn)保存下來(lái))

項(xiàng)目中運(yùn)用到的(僅供參考)
需求:根據(jù)點(diǎn)擊子節(jié)點(diǎn)查詢沒(méi)有就一直向上查
思路:拿到樹(shù)形結(jié)構(gòu)數(shù)組直接遞歸查詢
難點(diǎn):
1)獲取懶加載的樹(shù)形結(jié)構(gòu),(因?yàn)閼屑虞d封裝的數(shù)據(jù)結(jié)構(gòu)是分開(kāi)裝的)
2)拼接成樹(shù)形結(jié)構(gòu)在處理
下面為實(shí)現(xiàn)例子 只列出大概實(shí)現(xiàn)思路
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>悲傷敵敵畏</title>
</head>
<body>
<script type="text/javascript">
/**
分析:
1.獲取樹(shù)節(jié)點(diǎn)的數(shù)據(jù),
2.因?yàn)槭莑ist結(jié)構(gòu)的,先存放在map里面(遞歸)
3.拼接成層級(jí)數(shù)據(jù) 返回(遞歸)
4.根據(jù)parentId 查詢父級(jí)(遞歸)
*/
const data = [
{
childNodes: [
{childNodes: [{childNodes:[],data:{id: 5, name: "測(cè)試5", parentId: 3}}], data: {id: 3, name: "測(cè)試3", parentId: 1}},
{childNodes: [], data: {id: 4, name: "測(cè)試4", parentId: 1}}
],
data: {id: 1, name: "測(cè)試1", parentId: null}
},
{
childNodes: [],
data: {id: 2, name: "測(cè)試2", parentId: null}
},
];
console.info("要處理的數(shù)據(jù)結(jié)構(gòu) >>>",data)
//使用函數(shù)
forChildren(data)
function forChildren(list){
//TODO 轉(zhuǎn)成map結(jié)構(gòu),用于比較
let map = {};
let forMap = function (arr){
for (const item of arr) {
map[item.data.id] = item.data
if (item.childNodes.length > 0){
forMap(item.childNodes)
}
}
}
forMap(list)
console.log("封裝的map >>>",map)
//TODO 拼接成層級(jí)數(shù)據(jù):
let result = [];
let forList =function(arr){
for (const item of arr) {
item.data.children = [] //為每個(gè)data添加一個(gè)數(shù)組
if (item.data.parentId === null){ //判斷是否為最外層(最外層一般都是空或者-1)
result.push(item.data)
}
if (item.childNodes.length > 0){
for (const children of item.childNodes) {
let paren = map[children.data.parentId]
paren.children.push(children.data)
forList(item.childNodes)
}
}
}
}
forList(list)
console.log("拼接好的樹(shù)形結(jié)構(gòu)",result)
//TODO 根據(jù)子節(jié)點(diǎn)查找上面的每個(gè)父節(jié)點(diǎn)
let parents = []
let forParent = function (arr,parentId){
for (const item of arr) {
if (item.id === parentId){
parents.push(item)
forParent(result,item.parentId)
break
}else {
if (item.children){
forParent(item.children,parentId)
}
}
}
}
forParent(result,5)
console.log("父級(jí)以及自己的數(shù)據(jù)",parents)
}
</script>
</body>
</html>總結(jié)
到此這篇關(guān)于JavaScript遞歸操作樹(shù)形結(jié)構(gòu)的文章就介紹到這了,更多相關(guān)js遞歸操作樹(shù)形結(jié)構(gòu)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
jQuery鼠標(biāo)懸浮鏈接彈出跟隨圖片實(shí)例代碼
這篇文章主要介紹了jQuery鼠標(biāo)懸浮鏈接彈出跟隨圖片實(shí)例代碼,需要的朋友可以參考下2016-01-01
利用js制作html table分頁(yè)示例(js實(shí)現(xiàn)分頁(yè))
這篇文章主要介紹了利用js制作html table的分頁(yè)示例(js實(shí)現(xiàn)分頁(yè)),需要的朋友可以參考下2014-04-04
JavaScript canvas繪制圓形加載進(jìn)度條
這篇文章主要為大家詳細(xì)介紹了JavaScript canvas繪制圓形加載進(jìn)度條,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06
淺談js的ajax的異步和同步請(qǐng)求的問(wèn)題
下面小編就為大家?guī)?lái)一篇淺談js的ajax的異步和同步請(qǐng)求的問(wèn)題。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-10-10
javascript實(shí)現(xiàn)tab切換特效
這篇文章主要介紹了javascript實(shí)現(xiàn)tab切換特效,實(shí)現(xiàn)的方法很簡(jiǎn)單,特別適合初學(xué)者學(xué)習(xí)javascript實(shí)現(xiàn)tab切換特效,tab切換再也不是問(wèn)題,需要的朋友可以參考下2015-11-11
JavaScript進(jìn)階知識(shí)點(diǎn)作用域詳解
這篇文章主要介紹了JavaScript進(jìn)階講解一作用域,主要包括作用域、函數(shù)、閉包、面向?qū)ο?、ES新特性、事件循環(huán)、微任務(wù)、宏任務(wù)、內(nèi)存管理、Promise、await、?asnyc、防抖、節(jié)流等等知識(shí)點(diǎn),需要的朋友可以參考下2022-05-05

