当前位置: 首页 > news >正文

Tree数据处理

文章目录

  • 一、Tree数据重置
  • 二、Tree拆分成二级数据
    • 1、过滤数据
    • 2、二级数据

Tree组件的数据处理往往需要使用递归,本文归纳一下常见的数据处理情景,持续更新;

一、Tree数据重置

  • 递归的标志就是寻找子元素的集合字段,一般为children,将所有节点依次过滤,
  • 遍历过程类似于先序遍历,递归得到的返回值重新组成新的children数据,这个过程类似于后序遍历
  • 遍历过程主要是增加必要的属性比如value、key,还可以根据节点数据动态设置icon
  • 注意展开项expandedKeys的收集,根据数据自主控制
import { SmileOutlined } from "@ant-design/icons";
import { Button, Form, Tree } from "antd";
import React, { useMemo } from "react";
const treeDataTest = [{ name: "0", id: "0", children: [{ name: "1", id: "0-0" }] },{name: "1",id: "1",sub: [{name: "1-0",id: "1-0",children: [{ name: "1-0-0", id: "1-0-0" },{ name: "1-0-1", id: "1-0-1" }]},{name: "2-0",id: "2-0",sub: [{name: "2-0-0",id: "2-0-0",sub: [{ name: "2-0-0-0", id: "2-0-0-0", children: [{ name: "2-0-0-0-0", id: "2-0-0-0-0" }] }]}]}]}
];
export default function TreePage() {const [form] = Form.useForm();const [expandedKeys, setExpandedKeys] = React.useState([]);const labelWarpBtn = {offset: 6,span: 14};const onValuesChange = (changedValues, allValues) => {console.log("changedValues: ", changedValues);console.log("allValues: ", allValues);};// 转换每一个节点,只区分children、sub属性、icon属性const transformData = (data, expandedKeys) => {data.forEach((item) => {item.title = item.name;item.key = item.id;if (item.children) {expandedKeys.push(item.key);item.children = transformData(item.children, expandedKeys);} else if (item.sub) {item.children = transformData(item.sub, expandedKeys);} else {item.icon = <SmileOutlined />;}});return data;};// 单纯过滤数据添加属性const treeData = useMemo(() => {const expandedKeys = [];const data = transformData(treeDataTest, expandedKeys);setExpandedKeys(expandedKeys);return data;}, [treeDataTest]);return (<div><Form form={form} labelCol={{ span: 6 }} wrapperCol={{ span: 14 }} onValuesChange={onValuesChange}><Form.Item name="tree" label="tree">{/* fieldNames={{ title: "name", key: "id", children: "children" }} */}{/* 这里只是初步定义,只能扩充三个字段,想要更灵活的属性,在数据层修改就好了 */}{/* 一般处理数据后还要关注expandedKeys等属性 */}<Tree treeData={treeData} expandedKeys={expandedKeys} onExpand={setExpandedKeys} showIcon></Tree></Form.Item><Form.Item wrapperCol={labelWarpBtn}><Button type="primary" htmlType="submit" onClick={console.log(form.getFieldsValue())}>Submit</Button></Form.Item></Form></div>);
}

二、Tree拆分成二级数据

1、过滤数据

  • 过滤不存在有效数据的节点,假设num表示该节点下级存在的有效数据的数量,通过num可以进行空数据过滤
  • 递归中遇到报错可以使用debugger查看问题,调用次数太多使用console也无法定位
const treeDataTest = [{ name: "0", id: "0", children: [{ name: "1", id: "0-0" }] },{name: "1",id: "1",sub: [{name: "1-0",id: "1-0",children: [{ name: "1-0-0", id: "1-0-0" },{ name: "1-0-1", id: "1-0-1" }]},{name: "2-0",id: "2-0",sub: [{name: "2-0-0",id: "2-0-0",sub: [{ name: "2-0-0-0", id: "2-0-0-0", children: [{ name: "2-0-0-0-0", id: "2-0-0-0-0" }] }]}]}]}
];// 过滤数据,只展示存在有效数据的节点const filterData = (data) => {const filter = (arr) => {return arr.filter((item) => {if (item.num > 0) {// debugger;if (item.sub?.length > 0) {item.sub = filter(item.sub);}return true;}return false;});};return filter(JSON.parse(JSON.stringify(data)));};

2、二级数据

  • 当需要拆分成两级时,需要把中间层级省略,保留末端children数据(假设有效数据都保存在children中)
  • 设定目标数据的层级为两级,就可以遍历最外层,而内层递归,逐个往数组里添加末端children数据
import { SmileOutlined } from "@ant-design/icons";
import { Button, Form, Tree } from "antd";
import React, { useCallback, useMemo } from "react";
const treeDataTest = [{ name: "0", id: "0", num: 1, children: [{ name: "1", id: "0-0" }], sub: [] },{name: "1",id: "1",num: 3,sub: [{name: "1-0",id: "1-0",num: 2,children: [{ name: "1-0-0", id: "1-0-0" },{ name: "1-0-1", id: "1-0-1" }]},{name: "2-0",id: "2-0",num: 1,sub: [{name: "2-0-0",id: "2-0-0",num: 1,sub: [{ name: "2-0-0-0", id: "2-0-0-0", num: 1, children: [{ name: "2-0-0-0-0", id: "2-0-0-0-0" }] }]}]}]},{name: "2",id: "2",num: 0,sub: [{ name: "2-0", id: "2-0", num: 0, sub: [{ name: "2-0-0", id: "2-0-0", num: 0 }] }]}
];
export default function TreePage() {const [form] = Form.useForm();const [expandedKeys, setExpandedKeys] = React.useState([]);const labelWarpBtn = {offset: 6,span: 14};const onValuesChange = (changedValues, allValues) => {console.log("changedValues: ", changedValues);console.log("allValues: ", allValues);};// 转换为二级树结构,方便展示数据const transformChildrenOnly = (data) => {data.forEach((item) => {item.title = item.name;item.key = item.id;item.icon = <SmileOutlined />;});return data;};const transformChildren = (data, arr) => {data.forEach((item) => {// 这里递归的条件仅限于sub,因为他是叶子节点,不被需要// 如果有level层级,可以采取更灵活的条件去拆分数据if (item.children) {arr.push(...transformChildrenOnly(item.children));} else if (item.sub) {transformChildren(item.sub, arr);}});return data;};const transformDataToSecondTree = useCallback((data) => {const newData = [];const expandedKeys = [];data.forEach((item) => {const arr = [];item.title = item.name;item.key = item.id;expandedKeys.push(item.key);if (item.children) {// 如果第二层就是childrenarr.push(...transformChildrenOnly(item.children));} else if (item.sub) {// 如果第二层是sub属性,sub代表他是叶子节点,不是最终节点transformChildren(item.sub, arr);}newData.push({ ...item, children: arr });});setExpandedKeys(expandedKeys);return newData;}, []);// 过滤数据,只展示存在有效数据的节点const filterData = (data) => {const filter = (arr) => {return arr.filter((item) => {if (item.num > 0) {// debugger;if (item.sub?.length > 0) {item.sub = filter(item.sub);}return true;}return false;});};return filter(JSON.parse(JSON.stringify(data)));};// 转换为二级树结构const treeData = useMemo(() => transformDataToSecondTree(filterData(treeDataTest)), [treeDataTest]);return (<div><Form form={form} labelCol={{ span: 6 }} wrapperCol={{ span: 14 }} onValuesChange={onValuesChange}><Form.Item name="tree" label="tree">{/* fieldNames={{ title: "name", key: "id", children: "children" }} */}{/* 这里只是初步定义,只能扩充三个字段,想要更灵活的属性,在数据层修改就好了 */}{/* 一般处理数据后还要关注expandedKeys等属性 */}<Tree treeData={treeData} expandedKeys={expandedKeys} onExpand={setExpandedKeys} showIcon></Tree></Form.Item><Form.Item wrapperCol={labelWarpBtn}><Button type="primary" htmlType="submit" onClick={console.log(form.getFieldsValue())}>Submit</Button></Form.Item></Form></div>);
}

案例图片

相关文章:

Tree数据处理

文章目录 一、Tree数据重置二、Tree拆分成二级数据1、过滤数据2、二级数据 Tree组件的数据处理往往需要使用递归&#xff0c;本文归纳一下常见的数据处理情景&#xff0c;持续更新&#xff1b; 一、Tree数据重置 递归的标志就是寻找子元素的集合字段&#xff0c;一般为children…...

idea配置gitee仓库

idea配置gitee 0、fork开源项目 到自己的仓库&#xff0c;这一步相当于创建了一个自己的git仓库&#xff0c;并复制了别人的开源代码。 注意&#xff1a;如果直接下载别人的开源项目&#xff0c;需要从新配置git仓库信息&#xff0c;因为开源项目一般都设置了git信息。而修改…...

SpringBoot 事务

事务是一组操作的集合, 是一个不可分割的操作.会把所有的操作作为一个整体, 一起向数据库提交或者是撤销操作请求. 所以这组操作要么同时成功, 要么同时失败. 为什么需要事务? 我们在进行程序开发时, 也会有事务的需求. 比如转账操作: 第一步&#xff1a;A 账户 -100 元. …...

我的JAVA-Web基础(1)

1.HTML 2.css CSS&#xff08;层叠样式表&#xff09;提供了多种选择器来定位HTML文档中的元素&#xff0c;以便可以应用样式。以下是三种常用的选择器简述&#xff1a; ID 选择器&#xff1a; ID选择器使用HTML元素的id属性来定位单个元素。每个页面中id应该是唯一的&#xf…...

【Leetcode 热题 100】207. 课程表

问题背景 你这个学期必须选修 n u m C o u r s e s numCourses numCourses 门课程&#xff0c;记为 0 0 0 到 n u m C o u r s e s − 1 numCourses - 1 numCourses−1。 在选修某些课程之前需要一些先修课程。 先修课程按数组 p r e r e q u i s i t e s prerequisites p…...

从CreateDialogIndirectParam起---我与大模型对话

前言&#xff1a; 对当前的大模型来说&#xff0c;一切皆程序&#xff0c;皆标准。只能按照推定的线路行走&#xff0c;就像机器人走进死胡同&#xff0c;不停的踏步也不回头。除非人为去干预它。其实我提出的这个问题前是因为我不清楚了解一部分WinAPI有着严格的检查机制和自毁…...

重温设计模式--建造者模式

文章目录 建造者模式&#xff08;Builder Pattern&#xff09;概述建造者模式UML图作用&#xff1a;建造者模式的结构产品&#xff08;Product&#xff09;&#xff1a;抽象建造者&#xff08;Builder&#xff09;&#xff1a;具体建造者&#xff08;Concrete Builder&#xff…...

CSS(五):定位

目录 相对定位 绝对定位 固定定位 在 CSS 中&#xff0c;position 属性用于控制元素的定位方式&#xff0c;使我们可以精确地控制元素在页面上的位置。定位分为相对定位、绝对定位、和固定定位 相对定位 相对定位&#xff1a;position: relative; 相对定位意味着元素的位置…...

JSON 系列之2:JSON简单查询

本文为Oracle数据库JSON学习系列的第2篇&#xff0c;讲述如何对存储在数据库中的JSON文档进行简单的查询。 创建测试表&#xff0c;插入2条数据&#xff1a; DROP TABLE colortab PURGE;CREATE TABLE colortab (id NUMBER,color VARCHAR2(4000),CONSTRAINT ensure_json CH…...

SQL 简单查询

目录 一、投影查询 1、指定特定列查询 2、修改返回列名查询 3、计算值查询 二、选择查询 1、使用关系表达式 2、使用逻辑表达式 3、使用 BETWEEN关键字 4、使用 IN关键字 5、使用 LIKE关键字 6、使用 IS NULL/ NOT NULL关键字 7、符合条件查询 三、聚合函数查询 一…...

YOLOv9-0.1部分代码阅读笔记-metrics.py

metrics.py utils\metrics.py 目录 metrics.py 1.所需的库和模块 2.def fitness(x): 3.def smooth(y, f0.05): 4.def ap_per_class(tp, conf, pred_cls, target_cls, plotFalse, save_dir., names(), eps1e-16, prefix""): 5.def compute_ap(recall, prec…...

KaiOS 4.0 | DataCall and setupData implemention

相关文档 1、KaiOS 3.1 系统介绍 KaiOS 系统框架和应用结构(APP界面逻辑)文章浏览阅读842次,点赞17次,收藏5次。对于Java开发者而言,理解JS的逻辑调用是有点困难的。而KaiOS webapp开发又不同于现代的web开发,更像chrome浏览器内嵌模式。在这里梳理一下kaios平台web应用…...

nginx-rtmp服务器搭建

音视频服务器搭建 本文采用 nginx/1.18.0和nginx-rtmp-module模块源代码搭建RTMP流媒体服务器 流程 查看当前服务器的nginx版本下载nginx和nginx-rtmp-module源代码重新编译nginx&#xff0c;并进行相关配置&#xff08;nginx.conf、防火墙等&#xff09;客户端测试连接测试搭…...

[c++进阶(三)]单例模式及特殊类的设计

1.前言 在实际场景中,总会遇见一些特殊情况,比如设计一个类,只能在堆上开辟空间, 或者是设计一个类只能实例化一个对象。那么我们应该如何编写代码呢&#xff1f;本篇将会详细的介绍 本章重点&#xff1a; 本篇文章着重讲解如何设计一些特殊 的类,包括不能被拷贝,只能在栈/堆上…...

企业内训|高智能数据构建和多模态数据处理、Agent研发及AI测评技术内训-吉林省某汽车厂商

吉林省某汽车厂商为提升员工在AI大模型技术方面的知识和实践能力&#xff0c;举办本次为期8天的综合培训课程。本课程涵盖“高智能数据构建与智驾云多模态数据处理”、“AI Agent的研发”和“大模型测评”三大模块。通过系统梳理从非结构化数据的高效标注与融合&#xff0c;到L…...

009 Qt_显示类控件_QLCDNumber、ProgressBar、Calendar

文章目录 前言LCD NumberProgressBarCalendar Widget 小结 前言 本文将会向你介绍显示类控件中QLCDNumber显示数字、ProgressBar进度条、Calendar日历 LCD Number QLCDNumer 是⼀个专门用来显示数字的控件. 类似于 “老式计算器” 的效果. 属性说明intValueQLCDNumber 显示…...

--spring.profiles.active=prod

rootproduct-qualification:~# ps -ef | grep java root 5110 1 3 16:57 ? 00:00:54 java -jar productQualification.jar --spring.profiles.activeprod root 6476 5797 0 17:26 pts/0 00:00:00 grep --colorauto java好的&#xff0c;你使用 ps …...

深入解析JVM中对象的创建过程

1. 引言 对象是面向对象编程的核心概念之一&#xff0c;它们封装了数据和行为&#xff0c;构成了应用程序的基本构建块。然而&#xff0c;在Java语言中&#xff0c;每当使用new关键字或其他方式创建一个新对象时&#xff0c;背后发生了什么&#xff1f;这个问题的答案隐藏在JV…...

使用开源在线聊天工具Fiora轻松搭建个性化聊天平台在线交流

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家&#xff1a;人工智能教程 文章目录 前言1.关于Fiora2.安装Docker3.本地部署Fiora4.使用Fiora5.cpolar内网穿透工具安装6.创建远程连接公网地址7.固定Uptime …...

ffmpeg之显示一个yuv照片

显示YUV图片的步骤 1.初始化SDL库 目的&#xff1a;确保SDL库正确初始化&#xff0c;以便可以使用其窗口、渲染和事件处理功能。操作&#xff1a;调用 SDL_Init(SDL_INIT_VIDEO) 来初始化SDL的视频子系统。 2.创建窗口用于显示YUV图像&#xff1a; 目的&#xff1a;创建一个…...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

Python爬虫实战:研究feedparser库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

电脑插入多块移动硬盘后经常出现卡顿和蓝屏

当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时&#xff0c;可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案&#xff1a; 1. 检查电源供电问题 问题原因&#xff1a;多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

JDK 17 新特性

#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持&#xff0c;不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的&#xff…...

Rapidio门铃消息FIFO溢出机制

关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系&#xff0c;以下是深入解析&#xff1a; 门铃FIFO溢出的本质 在RapidIO系统中&#xff0c;门铃消息FIFO是硬件控制器内部的缓冲区&#xff0c;用于临时存储接收到的门铃消息&#xff08;Doorbell Message&#xff09;。…...

短视频矩阵系统文案创作功能开发实践,定制化开发

在短视频行业迅猛发展的当下&#xff0c;企业和个人创作者为了扩大影响力、提升传播效果&#xff0c;纷纷采用短视频矩阵运营策略&#xff0c;同时管理多个平台、多个账号的内容发布。然而&#xff0c;频繁的文案创作需求让运营者疲于应对&#xff0c;如何高效产出高质量文案成…...

LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》

这段 Python 代码是一个完整的 知识库数据库操作模块&#xff0c;用于对本地知识库系统中的知识库进行增删改查&#xff08;CRUD&#xff09;操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 &#x1f4d8; 一、整体功能概述 该模块…...

现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?

现有的 Redis 分布式锁库&#xff08;如 Redisson&#xff09;相比于开发者自己基于 Redis 命令&#xff08;如 SETNX, EXPIRE, DEL&#xff09;手动实现分布式锁&#xff0c;提供了巨大的便利性和健壮性。主要体现在以下几个方面&#xff1a; 原子性保证 (Atomicity)&#xff…...

CSS | transition 和 transform的用处和区别

省流总结&#xff1a; transform用于变换/变形&#xff0c;transition是动画控制器 transform 用来对元素进行变形&#xff0c;常见的操作如下&#xff0c;它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...