JS怎样实现扁平数据与tree转换,方法是什么
Admin 2022-09-06 群英技术资讯 304 次浏览
有时我们拿到的数据的数据结构可能不是理想的,那么此时就要求前端程序员,具有改造数据的能力。例如拿到扁平的数据, 但我们要应用在 tree 树形组件或 Cascader 级联选择器组件中,这样的组件要求数据结构是非扁平的的具有层级递进关系的 tree 结构。
总之就是说,提供数据的接口给到的数据,未必符合要求,而当我们又无法令他人为为我们改变时,需求和要求就来到了前端程序员这里, 所以得具备这样的数据处理能力。
下面是将举两个数据改造的例子:
扁平化函数
/**
* 扁平化:将具有层级递进关系结构的 tree 数据扁平化
*
* @param treeList 有层级递进关系结构的 tree 数据
* @param flatList 用于接收扁平化结果的变量
* @returns {*} 返回扁平化结果
*/
function treeToFlat (treeList, flatList) {
// flatList.length > 9999 是考虑底线保护原则,出于极限保护的目的设置的,可不设或按需设置。
if (flatList.length > 9999) {
return
}
treeList.map(e => {
flatList.push(e)
// 递归:有条件的自己调用自己,条件是 e.children.length 为真
if (e.children && e.children.length) {
treeToFlat(e.children, flatList)
}
})
// console.log('扁平化后:', flatList)
return flatList
}
反扁平化函数
/**
* 反扁平化:将扁平结构的 flat 数据转换为具有层级递进关系结构的 tree 数据
*
* @param flatList 扁平结构的数据
* @param treeList 用于接收反扁平化结果的变量
* @returns {*} 返回反扁平化结果
*/
function flatToTree (flatList, treeList) {
flatList.map(e => {
// 以 e.pid===null,作为判断是不是根节点的依据,或者直接写死根节点(如果确定的话),
// 具体以什么作为判断根节点的依据,得看数据的设计规则,通常是判断层级或是否代表根节点的标记
if (e.pid === null) {
// 避免出现重复数据
const index = treeList.findIndex(sub => sub.id === e.id)
if (index === -1) {
treeList.push(e)
}
}
flatList.map(e2 => {
if (e2.pid === e.id) {
// 避免出现重复数据
const index = e.children.findIndex(sub => sub.id === e2.id)
if (index === -1) {
e.children.push(e2)
}
}
})
})
demo 测试结果截图如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>扁平数据转tree与tree数据扁平化 Demo</title>
</head>
<body>
<h1>扁平数据转tree与tree数据扁平化</h1>
<script>
window.onload = function () {
test()
}
function test () {
let flatList = [],
treeList = [
{
id: 1,
pid: null,
label: '第一层',
value: '1',
children: [
{
id: 2,
pid: 1,
label: '第二层1',
value: '2.1',
children: []
},
{
id: 3,
pid: 1,
label: '第二层2',
value: '2.2',
children: []
},
{
id: 4,
pid: 1,
label: '第二层3',
value: '2.3',
children: [
{
id: 5,
pid: 4,
label: '第三层1',
value: '3.1',
children: []
},
{
id: 6,
pid: 4,
label: '第三层2',
value: '3.2',
children: []
},
]
},
]
}
]
console.log('原始 tree 数据:', JSON.parse(JSON.stringify(treeList)))
// 扁平化
console.log('tree =>flat,扁平化后:', treeToFlat(JSON.parse(JSON.stringify(treeList)), flatList))
// 反扁平化,SON.parse(JSON.stringify()) 为了实现深拷贝
console.log('flat =>tree,反扁平化后:', flatToTree(JSON.parse(JSON.stringify(flatList)), treeList))
}
/**
* 扁平化:将具有层级递进关系结构的 tree 数据扁平化
*
* @param treeList 有层级递进关系结构的 tree 数据
* @param flatList 用于接收扁平化结果的变量
* @returns {*} 返回扁平化结果
*/
function treeToFlat (treeList, flatList) {
// flatList.length > 9999 是考虑底线保护原则,出于极限保护的目的设置的,可不设或按需设置。
if (flatList.length > 9999) {
return
}
treeList.map(e => {
flatList.push(e)
// 递归:有条件的自己调用自己,条件是 e.children.length 为真
if (e.children && e.children.length) {
treeToFlat(e.children, flatList)
}
})
// console.log('扁平化后:', flatList)
return flatList
}
/**
* 反扁平化:将扁平结构的 flat 数据转换为具有层级递进关系结构的 tree 数据
*
* @param flatList 扁平结构的数据
* @param treeList 用于接收反扁平化结果的变量
* @returns {*} 返回反扁平化结果
*/
function flatToTree (flatList, treeList) {
flatList.map(e => {
// 以 e.pid===null,作为判断是不是根节点的依据,或者直接写死根节点(如果确定的话),
// 具体以什么作为判断根节点的依据,得看数据的设计规则,通常是判断层级或是否代表根节点的标记
if (e.pid === null) {
// 避免出现重复数据
const index = treeList.findIndex(sub => sub.id === e.id)
if (index === -1) {
treeList.push(e)
}
}
flatList.map(e2 => {
if (e2.pid === e.id) {
// 避免出现重复数据
const index = e.children.findIndex(sub => sub.id === e2.id)
if (index === -1) {
e.children.push(e2)
}
}
})
})
// console.log('反扁平化后:', treeList)
return treeList
}
</script>
</body>
</html>
这两个扁平化与反扁平化写法,感觉还有值得优化的方法,但暂时想不到。
此外,递归的应用也是值得注意的地方。
我理解的递归:有条件的自己调用自己
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
这篇文章主要讲解前端的状态管理,状态管理李娜就想到:Vuex、Redux、Flux、Mobx等等方案,不论哪种方案只要内容一多起来似乎都是令人头疼的问题,今天来聊一聊前端的状态管理,感兴趣的小伙伴可以参考参考下面文字具体内容
目录前言案例回顾原型的拓展前言设计模式呢最多的可能是用到类,我们去通过类来封装一些实用的方法,通过设计模式去实现各个方法之间的解耦等,由于JS中的继承是用原型链继承的,所以原型模式是用原型实例指向创建对象的类,使用于创建新的对象的类共享原型对象的属性以及方法案例比如我们现在需要实现一个页面上的轮播图,可能需要用到对轮播
目录ElementUI上传Base64编码后的图片安装ElementUI按需引入(当然如果需要你也可以全部引入)上传实现ElementUI把上传的图片转为Base64ElementUI上传Base64编码后的图片自我认为ElementUI还是一个很不错的写手机端的组件,所以这次做小项目的时候就用了ElementUI的U
这篇文章主要给大家介绍是linux中node卸载与安装步骤,小编认为是比较容易简单上手的,因此分享给大家作参考,有这方面需要的朋友可以看看,下面就跟随小编一起来了解一下吧。
这篇文章主要为大家详细介绍了原生JS实现图片轮播跑马灯效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008