当前位置:网站首页>js树形结构,根据里层id找出它所属的每层父级集合
js树形结构,根据里层id找出它所属的每层父级集合
2022-07-24 10:47:00 【会说法语的猪】
最近搞得一个小需求,就是有个树形结构,然后知道里层其中一个id,我们要找到它所属的每层父级节点,当然也包括它自己。因为之前还真没搞过这种,然后就想了下,完美实现,然后也找到了一个第三方库。接下来说下我的思路和处理方式
先上个测试数据
const tree = [
{
id: '1',
parentId: 0,
name: '山东省',
children: [
{
id: '1-1',
parentId: '1',
name: '济南市',
children: [
{
id: '1-1-1',
parentId: '1-1',
name: '历下区',
children: []
},
{
id: '1-1-2',
parentId: '1-1',
name: '历城区',
children: []
}
]
},
{
id: '1-2',
parentId: '1',
name: '菏泽市',
children: [
{
id: '1-2-1',
parentId: '1-2',
name: '郓城县',
children: []
},
{
id: '1-2-2',
parentId: '1-2',
name: '鄄城县',
children: []
}
]
}
]
}
]方式一: 自己处理
处理分为两步:
① 我会先将树形结构扁平化,处理为同级
② 遍历上面扁平后的的数据,先根据已知id找出第一个,然后再根据它的parentId再找,知道找到parentId为0(无上级)的为止,也是一个递归操作
然后下面贴上两个方法,分别对应上面的两步
// 1. 先将树形结构扁平化,处理为同级
function flatTree(tree) {
const list = []
tree.forEach(item => {
const o = JSON.parse(JSON.stringify(item))
if(o.children) delete o.children
list.push(o)
if(item.children && item.children.length) {
list.push(...flatTree(item.children))
}
})
return list
}
// 2. 遍历上面扁平后的的数据,先根据id找出第一个,然后再根据它的parentId再找,知道找到parentId为0的为止,也是一个递归操作
function getParentAreas(pid, list) {
const target = []
const o = list.find(item => item.id == pid) || {}
if(JSON.stringify(o) != '{}') target.push(o)
if(o.parentId) target.push(...getParentAreas(o.parentId, list))
return target
}接下来就是测试一下:
console.log(getParentAreas('1-1-2', flatTree(tree)), '----->>>')
// [
// { id: '1-1-2', parentId: '1-1', name: '历城区' },
// { id: '1-1', parentId: '1', name: '济南市' },
// { id: '1', parentId: 0, name: '山东省' }
// ]因为是根据里面找的,所以找出来的是从里层带外层,如果想反过来,再reverse一下就可以了
然后可以将上面的代码进行优化,因为处理数据用到了两个方法,所以我这里把这两个方法写到一个类中,我们在实例化的时候就去执行上述方法,直接拿到我们所需要的数据
class FindArrsById {
constructor(id, tree) {
this.id = id
this.flatArr = this.flatTree.call(this, tree)
this.parentAreas = this.getParentAreas.call(this, this.id, this.flatArr)
this.getParentNames.bind(this)
}
flatTree(tree) {
const list = []
tree.forEach(item => {
const o = JSON.parse(JSON.stringify(item))
if(o.children) delete o.children
list.push(o)
if(item.children && item.children.length) {
list.push(...this.flatTree(item.children))
}
})
return list
}
getParentAreas(pid, list) {
const target = []
let o = list.find(item => item.id == pid) || {}
if(JSON.stringify(o) != '{}') target.push(o)
if(o.parentId) target.push(...this.getParentAreas(o.parentId, list))
return target
}
// 该方法就是想拿到里面某个字段的集合
getParentNames(key) {
return this.parentAreas.map(item => item[key]).reverse()
}
}测试一下:
console.log(new FindArrsById('1-1-2', tree).getParentNames('name'), '----->>>')
// [ '山东省', '济南市', '历城区' ]方式二:采用 xe-utils 第三方库
xe-utils GitHub地址https://github.com/x-extends/xe-utils
文档: https://vxetable.cn/xe-utils/#/
安装:
npm install xe-utils使用:
const XEUtiles = require('xe-utils') // 或者使用ES6中的import都可以
let searchTree = XEUtiles.searchTree(tree, item => item.id == '1-1-2', { children: 'children' })
console.log(searchTree, '----->>>')
// [
// {
// id: '1',
// parentId: 0,
// name: '山东省',
// children: [
// {
// id: '1-1',
// parentId: '1',
// name: '济南市',
// children: [
// {
// id: '1-1-2',
// parentId: '1-1',
// name: '历城区',
// children: []
// }
// ]
// }
// ]
// }
// ]这个还是个满强大的库,我其实没用这个,这是后来做完之后发现的,里面有很多很多的方法,各种数据、方法的转换操作,用的6的话确实蛮方便的 。
但是我一般的话还是自己能处理就处理了,不是太复杂的话,能不用就不用了。
边栏推荐
- MySQL - full text index
- MySQL - 更新表中的数据记录
- [AHK] AutoHotKey tutorial ①
- [carving master learning programming] Arduino hands-on (59) - RS232 to TTL serial port module
- The method modified by private can be accessed through reflection. What is the meaning of private?
- Google cooperates with colleges and universities to develop a general model, proteogan, which can design and generate proteins with new functions
- Qt程序最小化托盘后,再弹出个msgbox,点击确定后程序退出问题解决
- 协议圣经-谈端口和四元组
- 很佩服的一个Google大佬,离职了。。
- After the QT program minimizes the tray, a msgbox pops up. Click OK and the program exits. The problem is solved
猜你喜欢

Image processing: rgb565 to rgb888

Qt程序最小化托盘后,再弹出个msgbox,点击确定后程序退出问题解决

OSPF includes special area experiments, mGRE construction and re release

563 pages (300000 words) overall design scheme of smart Chemical Park (phase I)

N叉树、page_size、数据库严格模式修改、数据库中delect和drop的不同

分布式事务处理方案大 PK!

Nirvana rebirth! Byte Daniel recommends a large distributed manual, and the Phoenix architecture makes you become a God in fire

零基础学习CANoe Panel(10)—— 复选框(CheckBox)

《nlp入门+实战:第二章:pytorch的入门使用 》
![[electronic device note 4] inductance parameters and type selection](/img/b1/6c5cb27903bc1093bf49e278e31353.png)
[electronic device note 4] inductance parameters and type selection
随机推荐
Adobe substance 3D Designer 2021 software installation package download and installation tutorial
零基础学习CANoe Panel(7)—— 开关/显示控件(Input/Output Box )
Adobe Substance 3D Designer 2021软件安装包下载及安装教程
Sentinel 三种流控模式
零基础学习CANoe Panel(8)—— 数据/文本编辑控件(Hex/Text Editor )
Overview of basic knowledge of binary tree
划分数据2
Set up mail server with dynamic ip+mdaemon
Sentinel three flow control effects
每日三题 7.22
Detailed explanation of Flink operation architecture
N叉树、page_size、数据库严格模式修改、数据库中delect和drop的不同
[micro service] eureka+ribbon realizes registration center and load balancing
Try the video for 5 minutes [easy to understand]
UVM——双向通信
Google cooperates with colleges and universities to develop a general model, proteogan, which can design and generate proteins with new functions
MySQL - 索引的隐藏和删除
Call bind apply simple summary
Sentinel 三种流控效果
Binlog and iptables prevent nmap scanning, xtrabackup full + incremental backup, and the relationship between redlog and binlog