js实现树形数据转成扁平数据的方法示例
作者:蔚莱先森 发布时间:2024-03-28 13:52:29
标签:js,树形数据,扁平数据
利用递归的方法循环树形数组,当遇到有children的对象再次调用递归函数循环children数组,每次循环的数据放入一个提前声明好的数组里,等所有递归函数执行完,这个数组即是想要得到的扁平数据数组。
let res = []
const fn = (source)=>{
source.forEach(el=>{
res.push(el)
el.children && el.children.length>0 ? fn(el.children) : ""
})
}
示例1
let res = [] // 用于存储递归结果(扁平数据)
// 递归函数
const fn = (source)=>{
source.forEach(el=>{
res.push(el)
el.children && el.children.length>0 ? fn(el.children) : "" // 子级递归
})
}
// 树形数据
const arr = [
{ id: "1", rank: 1 },
{ id: "2", rank: 1,
children:[
{ id: "2.1", rank: 2 },
{ id: "2.2", rank: 2 }
]
},
{ id: "3", rank:1,
children:[
{ id: "3.1", rank:2,
children: [
{ id:'3.1.1', rank:3,
children:[
{ id: "3.1.1.1", rank: 4,
children:[
{ id: "3.1.1.1.1", rank: 5 }
]
}
]
}
]
}
]
}
]
fn(arr) // 执行递归函数
console.log(res) // 查看结果
结果:
查看源码
扁平数据转成树形数据,请参考这篇文章:js实现无限层级树形数据结构(创新算法)
js将扁平结构数据转换为树形结构
递归实现
function transformTree (list) {
const tree = []
for (let i = 0, len = list.length; i < len; i++) {
if (!list[i].pid) {
const item = queryChildren(list[i], list)
tree.push(item)
}
}
return tree
}
function queryChildren (parent, list) {
const children = []
for (let i = 0, len = list.length; i < len; i++) {
if (list[i].pid === parent.id) {
const item = queryChildren(list[i], list)
children.push(item)
}
}
if (children.length) {
parent.children = children
}
return parent
}
尽管后续对上面的算法进行了很多优化,但是仍未离开递归,递归可能遇到的问题还是会有可能遇到
循环实现
随着进化,循环代替递归是必然的结果~
两次循环
开始使用循环实现时,使用了两次循环完成转换,先进行一次循环将数据转换成 map 结构,使其能通过 id 快速查询
function transformTree (list) {
const tree = []
const record = {}
const length = list.length
for (let i = 0; i < length; i++) {
const item = list[i]
item.children = [] // 重置 children
record[item.id] = item
}
for (let i = 0; i < length; i++) {
const item = list[i]
if (item.pid) {
if (record[item.pid]) {
record[item.pid].children.push(item)
}
} else {
tree.push(item)
}
}
return tree
}
上面的算法相较于递归的实现,不存在栈溢出的问题,而且是线性复杂度,效率已经提高了许多
一次循环
再进行一定的优化,最后变成一次循环完成树形构建
function transformTree (list) {
const tree = []
const record = {}
for (let i = 0, len = list.length; i < len; i++) {
const item = list[i]
const id = item.id
if (record[id]) {
item.children = record[id]
} else {
item.children = record[id] = []
}
if (item.pid) {
if (!record[item.pid]) {
record[item.pid] = []
}
record[item.pid].push(item)
} else {
tree.push(item)
}
}
}
使用对象变量的特性,使用 map 结构直接指向 children 数组,在循环中初始化的同时还能快速查找插入相应的 children 里,使其在一次循环内完成构建,最后附上完整版~
function transformTree (list, options = {}) {
const {
keyField = 'id',
childField = 'children',
parentField = 'parent'
} = options
const tree = []
const record = {}
for (let i = 0, len = list.length; i < len; i++) {
const item = list[i]
const id = item[keyField]
if (!id) {
continue
}
if (record[id]) {
item[childField] = record[id]
} else {
item[childField] = record[id] = []
}
if (item[parentField]) {
const parentId = item[parentField]
if (!record[parentId]) {
record[parentId] = []
}
record[parentId].push(item)
} else {
tree.push(item)
}
}
return tree
}
来源:https://blog.csdn.net/Mr_JavaScript/article/details/102833991
0
投稿
猜你喜欢
- 今天做了一个很简单的小项目,感受到了paramiko模块的强大,也深感自己Linux的功力不行~~一、需求二、简单需求分析及流程图需求很少,
- 如下图所示的文件,我们按文件名后缀对文件进行分类使用os和shutil首先导入对应的模块,将目标文件夹和到分类到的文件夹定义import o
- 本文实例讲述了python判断字符串是否纯数字的方法。分享给大家供大家参考。具体如下:判断的代码如下,通过异常判断不能区分前面带正负号的区别
- 使用mysql二进制方式启动连接您可以使用MySQL二进制方式进入到mysql命令提示符下来连接MySQL数据库。实例以下是从命令行中连接m
- python删除某个目录文件夹及文件的方法:#!/usr/bin/env pythonimport osimport shutildelLi
- 1-错误详情cmd下运行net start mysql启动MySQL服务:提示发生系统错误5。拒绝访问。cmd管理员模式运行可以启动MySQ
- 本文简述了通过创建database link实现ORACLE跨数据库查询的方法1.配置本地数据库服务器的tnsnames.ora文件$vi
- 1.前台ajax数据提交<form id="login_form" action="" met
- 在CSS规范中有一个渲染对象的概念,通常用一个盒子(box, rectangle)来表示。mozilla通过一个叫frame的对象对盒子进行
- 1、获取文件的创建、修改、访问时间# -*- encoding=utf-8 -*-import osimport timedef get_f
- ->基础环境Linux:ubuntu 16.04Python ; 2.7->修改hostname1:$sudo hostname
- 假如Excel中的数据如下:数据库建表如下:其中Id为自增字段:代码:using System;using System.Collectio
- Python之POST调用Restful接口示例# -*- coding: utf-8 -*-import jsonimport reimp
- nodejs和nginx都可以反向代理,解决跨域问题。本地服务const express = require('express
- 构造查询条件worm是一款方便易用的Go语言ORM库。worm支Model方式(持结构体字段映射)、原生SQL以及SQLBuilder三种模
- 今天搭了个“发短信”的页面,找朋友测试,没想到一位大侠直接弄了本长篇小说发我手机上……为了我的宝贝手机能继续健康澎湃,给文本区域(texta
- 写了一个小巧的jquery拾色工具,代码简单得不得了,只有这么几行:(function($){ $.fn.pickColor=fu
- 目录图片验证码登陆点击个人用户登录获取图片验证码识别并登陆识别较复杂验证码算法其他上一篇介绍了使用python模拟登陆网站,但是登陆的网站都
- sql server端口,我们可以通过\"服务器端网络试用工具\"和\"客户端实用工具\"来设定,设
- php本身没有提供返回毫秒数的函数,但提供了一个microtime()函数,该函数返回一个array,包含两个元素,一个是秒数,一个是小数表