001-Golang树型结构封装

001-Golang树型结构封装

日常问题001

注意:涉及到排序时,一般都是查库时就排好了,下面的操作不含排序实现

1.1 参数和返回值定义

这里的数据结构不使用 struct,用的 map,用什么我觉得都无所谓,根据具体情况来,反正最好还是用 struct 吧

// 核心数据结构-一般都是从数据库中获取的
var menus []map[string]interface{}
menu := map[string]interface{}{
	"parentId": 0,    // 父级id, 0表示当前菜单为最上级
	"id":       1,    // 菜单id
	"name":     "首页", // 菜单名称
}

// 返回值
var returnMenus []map[string]interface{}
returnMenu := map[string]interface{}{
	"parentId": 0,    // 父级id, 0表示当前菜单为最上级
	"id":       1,    // 菜单id
	"name":     "个人中心", // 菜单名称
	"children": map[string]interface{}{
		"parentId": 1,
		"id":       2,    
		"name":     "用户信息",
		"children": map[string]interface{}{},
	},
}

1.1 “最优解”(自我认可)

// 解题思想:都是地址操作,那么直接往父级地址塞
func getMenuTree(menus []map[string]interface{}) (realMenu []map[string]interface{}) {
	if len(menus) < 1 {
		return nil
	}
	formatMenu := make(map[int]map[string]interface{})
	for _, m := range menus {
		formatMenu[m["id"].(int)] = m
		if m["parentId"].(int) == 0 {
			realMenu = append(realMenu, m) // 需要返回的顶级菜单
		}
	}
	// 得益于都是地址操作,可以直接往父级塞
	for _, m := range formatMenu {
		if formatMenu[m["parentId"].(int)] == nil {
			continue
		}
		if formatMenu[m["parentId"].(int)]["children"] == nil {
			formatMenu[m["parentId"].(int)]["children"] = []map[string]interface{}{}
		}
		formatMenu[m["parentId"].(int)]["children"] = append(formatMenu[m["parentId"].(int)]["children"].([]map[string]interface{}), m)
	}
	return
}

1.2 蠢笨解

蠢笨蠢笨的操作,没有使用地址,也不使用递归

// 解题思路:先将菜单按层级分,然后一层一层往上封装
func getMenuTree(menus []map[string]interface{}) (realMenu []map[string]interface{}) {
	if len(menus) < 1 {
		return nil
	}

	// 临时存储当前层级所以子层级的菜单,比如:获取第一级时,tmp存储的就是二级及以下的菜单
	var tmp []map[string]interface{}

	// 储存格式 [level:[menuID:[menuInfo]]]
	formatMenu := make(map[int]map[int]map[string]interface{})
	level := 1

	// 按照菜单层级进行分组
	for {
		if len(menus) < 1 {
			break
		}
		for _, m := range menus {
			if formatMenu[level] == nil {
				formatMenu[level] = make(map[int]map[string]interface{})
			}
			// 第一次时,上级都为空;第二次时,都没有parentId=0的数据了
			if m["parentId"].(int) == 0 || formatMenu[level-1][m["parentId"].(int)] != nil {
				formatMenu[level][m["id"].(int)] = m
			} else {
				tmp = append(tmp, m)
			}
		}
		level++
		menus = tmp
		tmp = nil
	}

	// 组装为树型结构
	var parentMenu map[string]interface{}
	// 存储格式:[menuID:[menuInfo]]
	var selfMenus map[int]map[string]interface{}
	for i := level - 1; i > 1; i-- {
		selfMenus = formatMenu[i]
		// 如果查询没有进行排序,那么这里需要进行排序-但这里并未实现
		for _, selfMenu := range selfMenus {
			parentMenu = formatMenu[i-1][selfMenu["parentId"].(int)]
			if parentMenu == nil {
				continue
			}
			if parentMenu["children"] == nil {
				parentMenu["children"] = []map[string]interface{}{}
			}
			parentMenu["children"] = append(parentMenu["children"].([]map[string]interface{}), selfMenu)
		}
	}

	// 取第一级菜单,并将map[int]map[string]interface{}转化为[]map[string]interface{}
	for _, m := range formatMenu[1] {
		realMenu = append(realMenu, m)
	}
	formatMenu = nil
	return
}

1.3 递归解

注意 stackoverflow

// 递归,无话可说
func  getMenuTree(parentId float64, menus *[]map[string]interface{}) (childrenList []map[string]interface{}) {
	if len(*menus) < 1 {
		return nil
	}
	for _, systemMenu := range *menus {
		if systemMenu["parentId"].(float64) == parentId {
			systemMenu["children"] = getMenuTree(systemMenu["id"].(float64), menus)
			childrenList = append(childrenList, systemMenu)
		}
	}
	return
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值