英文:
How to convert an interface{} to nested tree in Golang
问题
传入的interface{}将被转换为[]map[string]interface{}。
原始数据类型是[]map[string]interface{}:
[
{
"ID": 1,
"Name": "Root",
"ParentID": 0,
"Path": "Root"
},
{
"ID": 2,
"Name": "Ball",
"ParentID": 1,
"Path": "Root/Ball"
},
{
"ID": 3,
"Name": "Foot",
"ParentID": 2,
"Depth": 2,
"Path": "Root/Ball/Foot"
}
]
希望得到的json类型为:
[
{
"ID": 1,
"Name": "Root",
"ParentID": 0,
"Path": "Root",
"Child": {
"ID": 2,
"Name": "Ball",
"ParentID": 1,
"Path": "Root/Ball",
"Child": {
"ID": 3,
"Name": "Foot",
"ParentID": 2,
"Depth": 2,
"Path": "Root/Ball/Foot"
}
}
}
]
如果使用PHP的方法:
$data = Raw data is array()...
$result = array();
$temp = array();
foreach($data as $item) {
if($item['ParentID'] == 0) {
$result[$item['ID']] = $item;
$temp[$item['ID']] =& $result[$item['ID']];
}else {
$temp[$item['ParentID']][$item['ID']] = $item;
$temp[$item['ID']] =& $temp[$item['ParentID']][$item['ID']];
}
}
return $result;
Golang代码无法运行:
func tree(array interface{}) map[int]*[]map[string]interface{} {
results := make(map[int]*map[string]interface{})
temp := make(map[int]map[string]*map[string]interface{})
for _, item := range maps(array) {
id := int(item["ID"].(float64))
pid := int(item["ParentID"].(float64))
if pid == 0 {
results[id] = item
temp[id]["c"] = &results[id]
} else {
temp[pid]["c"] = item
temp[id] = &temp[pid]["c"]
}
}
return results
}
func maps(val interface{}) []map[string]interface{} {
if b, err := json.Marshal(val); err == nil {
var maps []map[string]interface{}
json.Unmarshal(b, &maps)
return maps
}
return nil
}
我的英文不好,只能通过代码和谷歌翻译来表达。希望得到大家的帮助。
英文:
The incoming interface{} will be converted to []map[string]interface{}.
Raw data type is []map[string]interface{} :
[
{
"ID": 1,
"Name": "Root",
"ParentID": 0,
"Path": "Root"
},
{
"ID": 2,
"Name": "Ball",
"ParentID": 1,
"Path": "Root/Ball"
},
{
"ID": 3,
"Name": "Foot",
"ParentID": 2,
"Depth": 2,
"Path": "Root/Ball/Foot"
}
]
Hope to get type for json:
[
{
"ID": 1,
"Name": "Root",
"ParentID": 0,
"Path": "Root",
"Child": {
"ID": 2,
"Name": "Ball",
"ParentID": 1,
"Path": "Root/Ball",
"Child": {
"ID": 3,
"Name": "Foot",
"ParentID": 2,
"Depth": 2,
"Path": "Root/Ball/Foot"
}
}
}
]
if methods of php:
$data = Raw data is array()...
$result = array();
$temp = array();
foreach($data as $item) {
if($item['ParentID'] == 0) {
$result[$item['ID']] = $item;
$temp[$item['ID']] =& $result[$item['ID']];
}else {
$temp[$item['ParentID']][$item['ID']] = $item;
$temp[$item['ID']] =& $temp[$item['ParentID']][$item['ID']];
}
}
return $result
golang is not run:
func tree(array interface{}) map[int]*[]map[string]interface{} {
results := make(map[int]*map[string]interface{})
temp := make(map[int]map[string]*map[string]interface{})
for _, item := range maps(array) {
id := int(item["ID"].(float64))
pid := int(item["ParentID"].(float64))
if pid == 0 {
results[id] = item
temp[id]["c"] = &results[id]
} else {
temp[pid]["c"] = item
temp[id] = &temp[pid]["c"]
}
}
return results
}
func maps(val interface{}) []map[string]interface{} {
if b, err := json.Marshal(val); err == nil {
var maps []map[string]interface{}
json.Unmarshal(b, &maps)
return maps
}
return nil
}
my english is not good.
only be expressed by way of code and google translation.
Hope to get everyone's help.
答案1
得分: 0
一个好的开始是介绍以下代码:
type Post struct {
ID int
Name string
ParentID int
Depth int
Path string
}
var posts []Post
并使用encoding/json
包来将JSON列表Unmarshal
到Go语言的变量中。
英文:
A good start would be to introduce
type Post struct {
ID int
Name string
ParentID int
Depth int
Path string
}
var posts []Post
and use package encoding/json
to Unmarshal
the JSON list to a variable in Go.
答案2
得分: 0
解决方案
package main
import (
"encoding/json"
"fmt"
)
var indata string = `[
{
"ID": 1,
"Name": "Root",
"ParentID": 0,
"Path": "Root"
},
{
"ID": 2,
"Name": "Ball",
"ParentID": 1,
"Path": "Root/Ball"
},
{
"ID": 3,
"Name": "Foot",
"ParentID": 2,
"Depth": 2,
"Path": "Root/Ball/Foot"
}
]`
type Node struct {
ID int
Name string
ParentID int
Depth int
Path string
Child *Node
}
func main() {
nodes := []Node{}
err := json.Unmarshal([]byte(indata), &nodes)
if err != nil {
panic(err)
}
m := make(map[int]*Node)
for i, _ := range nodes {
//fmt.Printf("Setting m[%d] = <node with ID=%d>\n", n.ID, n.ID)
m[nodes[i].ID] = &nodes[i]
}
for i, n := range nodes {
//fmt.Printf("Setting <node with ID=%d>.Child to <node with ID=%d>\n", n.ID, m[n.ParentID].ID)
if m[n.ParentID] != nil {
m[n.ParentID].Child = &nodes[i]
}
}
outdata, err := json.Marshal(m[1])
if err != nil {
panic(err)
}
fmt.Println(string(outdata))
}
转到 https://play.golang.org/p/CMk1yhEOhd 进行测试。
英文:
Solution
package main
import (
"encoding/json"
"fmt"
)
var indata string = `[
{
"ID": 1,
"Name": "Root",
"ParentID": 0,
"Path": "Root"
},
{
"ID": 2,
"Name": "Ball",
"ParentID": 1,
"Path": "Root/Ball"
},
{
"ID": 3,
"Name": "Foot",
"ParentID": 2,
"Depth": 2,
"Path": "Root/Ball/Foot"
}
]`
type Node struct {
ID int
Name string
ParentID int
Depth int
Path string
Child *Node
}
func main() {
nodes := []Node{}
err := json.Unmarshal([]byte(indata), &nodes)
if err != nil {
panic(err)
}
m := make(map[int]*Node)
for i, _ := range nodes {
//fmt.Printf("Setting m[%d] = <node with ID=%d>\n", n.ID, n.ID)
m[nodes[i].ID] = &nodes[i]
}
for i, n := range nodes {
//fmt.Printf("Setting <node with ID=%d>.Child to <node with ID=%d>\n", n.ID, m[n.ParentID].ID)
if m[n.ParentID] != nil {
m[n.ParentID].Child = &nodes[i]
}
}
outdata, err := json.Marshal(m[1])
if err != nil {
panic(err)
}
fmt.Println(string(outdata))
}
Go to https://play.golang.org/p/CMk1yhEOhd to test it.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论