树型结构构建,模糊查询,过滤

2024-02-02 12:44

本文主要是介绍树型结构构建,模糊查询,过滤,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、前言

1、最近在做甘特图,有些需求和树型结构要求很大,看的是 pingCode,有搜索

在这里插入图片描述
2、还有抽取一部分树型结构的,如下是抽取上面的结构类型为需求的,重新组成树型

在这里插入图片描述

二、构建多颗树型结构

1、某些业务下,从数据库查询出来一堆数据后,希望构建树型结构,但是存在一种情况就是,可能这堆数据不是完整的,比如如下情况,我查询出来了除了D节点外的所有数据,那么这种情况下,如果使用正常的构建方式,那么构建出来的数据会丢失数据H,I,J,M,即使这四个节点的数据已经查询出来了,但是因为D节点缺失,导致无法链接上,如果是中间断开了,那断开的部分单独成一个树型结构
在这里插入图片描述

2、那有人说这不是正常的吗,你为啥D节点不查询出来,一颗完整的树是这样的啊,但是存在一些业务情况如下,上述的数据中除了D节点,其它节点的类型都是type1,而D节点的Type 是2,我现在就是想看type为1的,然后你给我形成树型结构

3、代码如下,其中模拟的时候,缺失节点999,所以结果如下,把节点999那一条结构,单独做一个树型结构返回,避免丢失
在这里插入图片描述

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;import java.util.*;
import java.util.stream.Collectors;class ChildHandle {public static void main(String[] args) {List<Node> mockData = mockData();List<List<Node>> lists = buildTree(mockData, 50);System.out.println(JSON.toJSONString(lists));}public static List<List<Node>> buildTree(List<Node> data, int maxDepth) {List<List<Node>> multipleTopNodeTreeResult = new ArrayList<>();if (CollUtil.isEmpty(data)) {return multipleTopNodeTreeResult;}Map<Integer, List<Node>> moduleMap = new HashMap<>(32);// 找出所有的父节点,因为有些数据并不是一个完整的树型树,如果是中间断开了,那断开的部分单独成一个树型结构HashSet<Integer> rootIds = new HashSet<>();Set<Integer> allIds = data.stream().map(Node::getId).collect(Collectors.toSet());for (Node module : data) {moduleMap.putIfAbsent(module.getPid(), new ArrayList<>());moduleMap.get(module.getPid()).add(module);// 当前的item的pid对应的数据不存在,说明从当前的item的pid就断开了,则为这个pid单独起一颗树if (!allIds.contains(module.getPid())) {rootIds.add(module.getPid());}}// 根据上述的判断,已经知道存在几颗树,则为每颗树构建结构rootIds.forEach(curTopNodeId -> {// 处理每一颗树List<Node> treeInCurTopNode = moduleMap.get(curTopNodeId);if (treeInCurTopNode != null) {// Sort root modulestreeInCurTopNode.sort(Comparator.comparingInt(Node::getSerialNumber));for (Node rootModule : treeInCurTopNode) {buildChildren(rootModule, moduleMap, 0, maxDepth);}} else {treeInCurTopNode = new ArrayList<>();}multipleTopNodeTreeResult.add(treeInCurTopNode);});return multipleTopNodeTreeResult;}private static void buildChildren(Node parentModule, Map<Integer, List<Node>> moduleMap, int depth, int maxDepth) {if (depth >= maxDepth) {// 达到深度限制,停止递归return;}List<Node> children = moduleMap.get(parentModule.getId());if (children != null) {// Sort childrenchildren.sort(Comparator.comparingInt(Node::getSerialNumber));parentModule.setChildren(children);for (Node child : children) {// 增加深度计数 限制最多递归多少次,避免OOMbuildChildren(child, moduleMap, depth + 1, maxDepth);}}}/*** 模拟数据** @return*/private static List<Node> mockData() {List<Node> result = new ArrayList<>();result.add(new Node(1, 0, "Root1"));result.add(new Node(2, 1, "Root1 A"));result.add(new Node(3, 1, "Root1 B"));result.add(new Node(4, 2, "Root1 A.1"));result.add(new Node(5, 2, "Root1 A.2"));result.add(new Node(6, 3, "Root1 B.1"));result.add(new Node(7, 3, "Root1 B.2"));result.add(new Node(8, 3, "Root1 C"));result.add(new Node(9, 8, "Root1 D"));result.add(new Node(1000, 0, "Root2"));result.add(new Node(1001, 1000, "Root2 A"));result.add(new Node(1002, 1000, "Root2 B"));return result;}
}class Node {private Integer id;/*** 父id,为0时说明自己就是第一层*/private Integer pid;/*** 名称*/private String name;/*** 排序*/private int serialNumber;/*** 子集*/private List<Node> children;public Integer getPid() {return pid;}public void setPid(Integer pid) {this.pid = pid;}public String getName() {return name;}public void setName(String name) {this.name = name;}public List<Node> getChildren() {return children;}public void setChildren(List<Node> children) {this.children = children;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public int getSerialNumber() {return serialNumber;}public void setSerialNumber(int serialNumber) {this.serialNumber = serialNumber;}public Node(Integer id, Integer pid, String name) {this.id = id;this.pid = pid;this.name = name;}public Node(Integer id, Integer pid, String name, int serialNumber, List<Node> children) {this.id = id;this.pid = pid;this.name = name;this.serialNumber = serialNumber;this.children = children;}
}

三、树型结构查询过滤

1、方法如下,其中存在一种情况就是查询到父节点满足过滤条件后,那么需不需要判断其子节点是否满足条件,如果不需要注释那段代码即可,如果需要接着往下判断则需要加上

/*** 树型查询** @param tree          树型集合* @param key           搜索的字段名称* @param value         搜索的值* @param childNodeName 子节点名称* @param <T>           数据具体对象* @return tree*/public <T> List<T> filterTree(List<T> tree, Function<JSONObject, Boolean> filterCondition, String childNodeName) {// 这个方法的原始文章 https://blog.csdn.net/weixin_44748212/article/details/131692471// 如果要保留子节点的话把注释的(// 去除子节点start - end )这段代码删掉即可if (CollUtil.isEmpty(tree)) {return new ArrayList<>();}
//        JSONArray arr = JSONArray.parseArray(JSON.toJSONString(tree)); //如果直接序列化,时间格式是 时间戳了JSONArray arr = JSONArray.parseArray(JSON.toJSONStringWithDateFormat(tree, DatePattern.NORM_DATETIME_PATTERN));JSONArray result = filterTree(arr, filterCondition, childNodeName);Type listType = new TypeReference<List<T>>() {}.getType();return JSON.parseObject(result.toJSONString(), listType);}private JSONArray filterTree(JSONArray tree, Function<JSONObject, Boolean> filterCondition, String childNodeName) {Iterator<Object> it = tree.iterator();while (it.hasNext()) {JSONObject current = (JSONObject) it.next();// 把当前节点给到外部,让外部判断是否满足条件if (Boolean.TRUE.equals(filterCondition.apply(current))) {// 去除子节点 startJSONArray childNodes = current.getJSONArray(childNodeName);if (!CollUtil.isEmpty(childNodes)) {JSONArray filterTree = filterTree(childNodes, filterCondition, childNodeName);if (CollUtil.isEmpty(filterTree)) {current.put(childNodeName, new JSONArray());}}// 去除子节点 endcontinue;}JSONArray childNodes = current.getJSONArray(childNodeName);if (!CollUtil.isEmpty(childNodes)) {filterTree(childNodes, filterCondition, childNodeName);}if (CollUtil.isEmpty(childNodes)) {it.remove();}}return tree;}

2、使用方式

List<ListDto> curTreeFilterResult = filterTree(curTree, currentNode -> {String titleValue = currentNode.getString("title");int serialNumber = currentNode.getIntValue("serialNumber");return StrUtil.contains(titleValue, params.getQuery())|| StrUtil.contains(dbDevmProjectInfo.getIdentifier().concat("-" + serialNumber), params.getQuery());}, "children");if (CollUtil.isNotEmpty(curTreeFilterResult)) {filterTreeResult.add(curTreeFilterResult);}

这篇关于树型结构构建,模糊查询,过滤的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/670746

相关文章

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

usaco 1.3 Mixing Milk (结构体排序 qsort) and hdu 2020(sort)

到了这题学会了结构体排序 于是回去修改了 1.2 milking cows 的算法~ 结构体排序核心: 1.结构体定义 struct Milk{int price;int milks;}milk[5000]; 2.自定义的比较函数,若返回值为正,qsort 函数判定a>b ;为负,a<b;为0,a==b; int milkcmp(const void *va,c

Retrieval-based-Voice-Conversion-WebUI模型构建指南

一、模型介绍 Retrieval-based-Voice-Conversion-WebUI(简称 RVC)模型是一个基于 VITS(Variational Inference with adversarial learning for end-to-end Text-to-Speech)的简单易用的语音转换框架。 具有以下特点 简单易用:RVC 模型通过简单易用的网页界面,使得用户无需深入了

pandas数据过滤

Pandas 数据过滤方法 Pandas 提供了多种方法来过滤数据,可以根据不同的条件进行筛选。以下是一些常见的 Pandas 数据过滤方法,结合实例进行讲解,希望能帮你快速理解。 1. 基于条件筛选行 可以使用布尔索引来根据条件过滤行。 import pandas as pd# 创建示例数据data = {'Name': ['Alice', 'Bob', 'Charlie', 'Dav

maven 编译构建可以执行的jar包

💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」👈,「stormsha的知识库」👈持续学习,不断总结,共同进步,为了踏实,做好当下事儿~ 专栏导航 Python系列: Python面试题合集,剑指大厂Git系列: Git操作技巧GO

自定义类型:结构体(续)

目录 一. 结构体的内存对齐 1.1 为什么存在内存对齐? 1.2 修改默认对齐数 二. 结构体传参 三. 结构体实现位段 一. 结构体的内存对齐 在前面的文章里我们已经讲过一部分的内存对齐的知识,并举出了两个例子,我们再举出两个例子继续说明: struct S3{double a;int b;char c;};int mian(){printf("%zd\n",s

嵌入式Openharmony系统构建与启动详解

大家好,今天主要给大家分享一下,如何构建Openharmony子系统以及系统的启动过程分解。 第一:OpenHarmony系统构建      首先熟悉一下,构建系统是一种自动化处理工具的集合,通过将源代码文件进行一系列处理,最终生成和用户可以使用的目标文件。这里的目标文件包括静态链接库文件、动态链接库文件、可执行文件、脚本文件、配置文件等。      我们在编写hellowor

ural 1026. Questions and Answers 查询

1026. Questions and Answers Time limit: 2.0 second Memory limit: 64 MB Background The database of the Pentagon contains a top-secret information. We don’t know what the information is — you