在实际的工作和业务需求中,我们经常会碰到树形数据结构,比如公司组织架构、组织层级、省市县或者事物的分类等等数据。那么在JavaScript中如何将数组转为树形结构和树形结构转为数组,本文就详细的来探究一下。 先来看看给出了一组怎样的数据,转换为怎样的树形结构。 后台接口返回或者面试官给你的数据:constlist〔{id:1,name:部门1,pid:0},{id:2,name:部门11,pid:1},{id:3,name:部门12,pid:1},{id:4,name:部门111,pid:2},{id:5,name:部门121,pid:3},{id:6,name:部门2,pid:0},{id:7,name:部门21,pid:6},{id:8,name:部门3,pid:0},〕 期望的处理后的数据:constlistTree〔{id:1,name:部门1,pid:0,children:〔{id:2,name:部门11,pid:1,children:〔{id:4,name:部门111,pid:2,children:〔〕}〕},{id:3,name:部门12,pid:1,children:〔{id:5,name:部门121,pid:3,children:〔〕}〕}〕},{id:6,name:部门2,pid:0,children:〔{id:7,name:部门21,pid:6,children:〔〕}〕},{id:8,name:部门3,pid:0,children:〔〕}〕 一、数组转换为树形结构 如果后台给了一个这样的数据说让前端自己去转换为树形结构或者面试官给你一组这样的数据让你手写一个转换方法,你会怎么处理? 1、递归实现递归查找获取子节点constgetChild(list,result,pid){for(constitemoflist){if(item。pidpid){constnewItem{。。。item,children:〔〕};result。push(newItem);getChild(list,newItem。children,item。id);}}}调用递归实现constlistToTree(list,pid){constresult〔〕;getChild(list,result,pid);}listToTree(list,0) 2、Map对象实现constlistToTree(list){最终树形结构输出的结果constresult〔〕;constitemMap{};for(constitemoflist){constiditem。constpiditem。if(!itemMap〔id〕){itemMap〔id〕{children:〔〕,};}itemMap〔id〕{。。。item,children:itemMap〔id〕〔children〕,};consttreeItemitemMap〔id〕;if(pid0){result。push(treeItem)}else{if(!itemMap〔pid〕){itemMap〔pid〕{children:〔〕}}itemMap〔pid〕。children。push(treeItem);}}}listToTree(list,0) 3、filter实现 这种方法很有意思,可能大多数人想不到,也是从大佬处学到的(读书人的是怎么能叫抄呢,应该叫窃)。constlistToTree(list,key){consttreelist。filter(function(parent){返回每一项得的子级数据constbranchArrlist。filter((child)parent。idchild〔key〕);parent。children〔〕;如果存在子级,则给父级添加一个children属性并赋值if(branchArr。length0){parent。childrenbranchA}返回第一层returnparent〔key〕0;});}传入原始数据和父级pid的keylistToTree(list,pid) 二、树形结构转换为数组 1、reduce取树行数据的所有子集functiontreeTransList(tree,key){returntree。reduce(function(con,item){varcalleearguments。con。push(item);if(item〔key〕item〔key〕。length0)item〔key〕。reduce(callee,con);},〔〕)。map(function(item){item〔key〕〔〕;})}treeTransList(listTree,children) 2、递归实现functiongetItem(tree,result){for(leti0;itree。i){if(tree〔i〕。children){getItem(tree〔i〕。children,result)deletetree〔i〕。}result。push(tree〔i〕)}}functiontreeToList(tree){constresult〔〕;getItem(tree,result);}treeToList(listTree) 3、广度优先遍历法functiontreeToList(tree,childNamechildren){设置临时数组,用来存放队列letqueen〔〕;设置输出数组,用来存放要输出的一维数组constresult〔〕;queenqueen。concat(tree);对树对象进行广度优先的遍历while(queen。length){constfirstqueen。shift();if(first〔childName〕){queenqueen。concat(first〔childName〕);deletefirst〔childName〕}result。push(first);}}treeToList(listTree,children)