分类标签Tree

需求:实现如下图所示标签树

https://i.postimg.cc/VkrwLQ5p/911.png

数据库

id name game_id first_classify second_classify
1 标签1 test123mumu 1 2
2 标签2 test123mumu 1 2
3 标签3 test123mumu 1 2
4 标签4 test123mumu 1 3
5 标签5 test123mumu 1 4
6 标签6 test123mumu 6 6
7 标签7 test123mumu 7 7
8 标签8 test123mumu 4 4
9 场景 test123mumu
10 test123mumu 性别
11 test123mumu 性别
12 test123mumu 性质

思路

主要思路是通过迭代 results(数据库中查出的全部数据) 中的每个标签,将它们组织成树形结构。首先,检查标签的分类层级(第一级和第二级),并根据需要创建新的树节点。然后,将当前标签作为子节点添加到相应的位置。最终,返回构建的树节点列表。

代码实现

func tree(results []*model.ArtMaterialTag) []*bean.Tree {
    // 创建一个空的树节点列表
    list := make([]*bean.Tree, 0)

    // 创建两个映射,用于跟踪第一级和第二级分类的索引位置
    firstIndexMapping, secondIndexMapping := make(map[string]int), make(map[string]int)

    // 遍历给定的结果列表
    for _, tag := range results {
        // 初始化一些变量
        firstIndex, secondIndex, haveFirst, haveSecond := 0, 0, false, false

        // 创建一个树节点,并填充其属性
        node := bean.Tree{
            ID:       tag.ID,
            Label:    tag.Name,
            Children: make([]bean.Tree, 0),
        }

        // 处理第一级分类
        if tag.FirstClassify != constants.EmptyString {
            haveFirst = true

            // 检查第一级分类是否已经存在于列表中,如果不存在,则创建一个新的节点
            v, ok := firstIndexMapping[tag.FirstClassify]
            if !ok {
                list = append(list, &bean.Tree{Label: tag.FirstClassify, Children: make([]bean.Tree, 0)})
                firstIndexMapping[tag.FirstClassify] = len(list) - 1
                firstIndex = len(list) - 1
            } else {
                firstIndex = v
            }
        }

        // 处理第二级分类
        if tag.SecondClassify != constants.EmptyString {
            haveSecond = true

            // 创建一个用于唯一标识第二级分类的键
            key := tag.FirstClassify + "-" + tag.SecondClassify

            // 检查第二级分类是否已经存在于列表中,如果不存在,则创建一个新的节点
            v, ok := secondIndexMapping[key]
            if !ok {
                list[firstIndex].Children = append(list[firstIndex].Children, bean.Tree{Label: tag.SecondClassify, Children: make([]bean.Tree, 0)})
                secondIndexMapping[key] = len(list[firstIndex].Children) - 1
                secondIndex = len(list[firstIndex].Children) - 1
            } else {
                secondIndex = v
            }
        }

        // 将当前节点添加到树的相应位置
        if haveSecond {
            list[firstIndex].Children[secondIndex].Children = append(list[firstIndex].Children[secondIndex].Children, node)
        } else if haveFirst {
            list[firstIndex].Children = append(list[firstIndex].Children, node)
        } else {
            list = append(list, &node)
            firstIndexMapping[tag.FirstClassify] = len(list) - 1
        }
    }

    // 返回构建的树节点列表
    return list
}

代码核心解读

firstIndexMappingsecondIndexMapping 是两个映射,它们用于跟踪已经存在的第一级和第二级分类在树结构中的索引位置。这两个映射的目的是为了避免重复创建相同的分类节点,以及在需要时能够快速找到已经存在的节点位置。以下是它们在代码中的作用和思路:

  1. firstIndexMapping 映射:
    • 这个映射的键是第一级分类的名称(tag.FirstClassify)。
    • 对应的值是该分类在 list 树节点列表中的索引位置。
    • 如果某个第一级分类在 firstIndexMapping 中不存在,那么代码会创建一个新的树节点表示该分类,并将它添加到 list 中,然后将新节点的索引位置存储在 firstIndexMapping 中。如果已经存在,代码会直接获取该分类在 list 中的索引位置。
  1. secondIndexMapping 映射:
    • 这个映射的键是一个组合键,由第一级分类和第二级分类组合而成(tag.FirstClassify + "-" + tag.SecondClassify)。
    • 对应的值是第二级分类在其父节点(第一级分类节点)的子节点列表中的索引位置。
    • 如果某个第二级分类在 secondIndexMapping 中不存在,那么代码会创建一个新的树节点表示该分类,并将它添加到其父节点的子节点列表中,然后将新节点的索引位置存储在 secondIndexMapping 中。如果已经存在,代码会直接获取该分类在其父节点的子节点列表中的索引位置。

这两个映射的使用可以有效地构建树结构,确保相同分类不会重复创建,而是被添加到已有的分类节点下。这有助于提高代码的效率和减少内存消耗,同时确保最终的树形结构正确反映了分类的层次关系。

返回json结果示例

{
  "code": 0,
  "message": "",
  "data": [
    {
      "id": 0,
      "label": "1",
      "children": [
        {
          "id": 0,
          "label": "2",
          "children": [
            {
              "id": 1,
              "label": "标签1",
              "children": []
            },
            {
              "id": 2,
              "label": "标签2",
              "children": []
            },
            {
              "id": 3,
              "label": "标签3",
              "children": []
            }
          ]
        },
        {
          "id": 0,
          "label": "3",
          "children": [
            {
              "id": 4,
              "label": "标签4",
              "children": []
            }
          ]
        },
        {
          "id": 0,
          "label": "4",
          "children": [
            {
              "id": 5,
              "label": "标签5",
              "children": []
            }
          ]
        }
      ]
    },
    {
      "id": 0,
      "label": "6",
      "children": [
        {
          "id": 0,
          "label": "6",
          "children": [
            {
              "id": 6,
              "label": "标签6",
              "children": []
            }
          ]
        }
      ]
    },
    {
      "id": 0,
      "label": "7",
      "children": [
        {
          "id": 0,
          "label": "7",
          "children": [
            {
              "id": 7,
              "label": "标签7",
              "children": []
            },
            {
              "id": 15,
              "label": "测试第二二条",
              "children": []
            }
          ]
        }
      ]
    },
    {
      "id": 0,
      "label": "4",
      "children": [
        {
          "id": 0,
          "label": "4",
          "children": [
            {
              "id": 8,
              "label": "标签8",
              "children": []
            },
            {
              "id": 13,
              "label": "标签9",
              "children": []
            }
          ]
        }
      ]
    },
    {
      "id": 9,
      "label": "场景",
      "children": []
    },
    {
      "id": 0,
      "label": "性别",
      "children": [
        {
          "id": 10,
          "label": "男",
          "children": []
        },
        {
          "id": 11,
          "label": "女",
          "children": []
        }
      ]
    },
    {
      "id": 0,
      "label": "性质",
      "children": [
        {
          "id": 12,
          "label": "中",
          "children": []
        }
      ]
    },
    {
      "id": 0,
      "label": "3",
      "children": [
        {
          "id": 0,
          "label": "4",
          "children": [
            {
              "id": 14,
              "label": "测试第一条",
              "children": []
            },
            {
              "id": 16,
              "label": "测试第一个饿",
              "children": []
            }
          ]
        }
      ]
    }
  ]
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,340评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,762评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,329评论 0 329
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,678评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,583评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,995评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,493评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,145评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,293评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,250评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,267评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,973评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,556评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,648评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,873评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,257评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,809评论 2 339

推荐阅读更多精彩内容

  • 创作过程中,如何让作品具有影视IP潜质? 近年来,有相当多的文学IP被改编成了影视剧,这些作品也因为影视剧的火爆也...
    高级编辑李编hwslbj阅读 33评论 0 0
  • Python网络爬虫库:轻松提取网页数据的利器 网络爬虫是一种自动化程序,它可以通过访问网页并提取所需的数据。Py...
    算优网络阅读 34评论 0 0
  • 一.经常装茶的杯子里面留下难看的茶渍,用牙膏洗之,非常干净; 二.仰头点眼药水时微微张嘴,这样眼睛就不会乱眨了; ...
    3298d817da64阅读 39评论 0 1
  • 建中四年,癸亥,公元783年(四) 1、卢杞切齿言曰:“朱泚忠贞,群臣莫及,奈何言其从乱,伤大臣心!臣请以百口保其...
    荒原苍狼阅读 101评论 0 2
  • 下一站:药王节 药王节,亦称药师节。壮族传统节日。传说药王是壮医药神。他发现药草,为人治病,还向 众人传授种药、采...
    就叫阿周吧阅读 98评论 0 0