最近在做一个无限分类,因为使用graphql,所以服务端结构没法预定义,只能让前端把无限级结构当字符串传过来。而前端是树级结构,不懒的做平铺处理,只能后端处理了。
golang无限级分类树结构转平铺,刚开始使用 []map[string]interface{}不行, 因为判言只能判断k 和 v 类型完全相同才是 []map[string]interface{},最后只能使用 []interface{}试试,结果成功了。
1. 参数中接收到的是json字符串:
name, _ := p.Args["name"].(string)
2. json字符串进行反序列化
m := []interface{}{}
err = json.Unmarshal([]byte(name), &m)
3. 调用递归
output := multi2tile(m, "")
4. input 值,有children字段递归
# 直接使用的示例
# [{\"name\":\"111\",\"child\":[{\"name\":\"111-2\", \"child\":[{\"name\":\"111-2-3\"}]}]}]
[{
"name": "111",
"children": [{
"name": "111-2",
"children": [{
"name": "111-2-3"
}]
}]
}]
5. 递归函数
func multi2tile(input []interface{}, pname string) []map[string]interface{} {
result := []map[string]interface{}{}
for _, item := range input {
it := item.(map[string]interface{})
// 有children递归
if it["children"] != nil && len(it["children"]) > 0 {
res := multi2tile(it["children"].([]interface{}), it["name"].(string))
result = append(result, res...)
delete(it, "children")
}
if pname != "" {
it["parent_name"] = pname
} else {
it["parent_name"] = ""
}
result = append(result, it)
}
return result
}
整体代码:
func main() {
// 输入数据
name := "[{\"name\":\"111\",\"child\":[{\"name\":\"111-2\", \"child\":[{\"name\":\"111-2-3\"}]}]}]"
// 反序列化
m := []interface{}{}
err = json.Unmarshal([]byte(name), &m)
if err != nil {
log.Error(err)
return
}
// 调用递归转平铺
output := multi2tile(m, "")
// 输出结果
fmt.Printf("output=%+v", output)
}
// 递归函数
func multi2tile(input []interface{}, pname string) []map[string]interface{} {
result := []map[string]interface{}{}
for _, item := range input {
it := item.(map[string]interface{})
// 有child递归
if it["children"] != nil {
res := multi2tile(it["children"].([]interface{}), it["name"].(string))
result = append(result, res...)
delete(it, "children")
}
if pname != "" {
it["parent_name"] = pname
} else {
it["parent_name"] = ""
}
result = append(result, it)
}
return result
}
结果:
output=[map[name:111-2-3 parent_name:111-2] map[name:111-2 parent_name:111] map[name:111 parent_name:]]