【问题标题】:Please help me figure out how to parse this json file [closed]请帮我弄清楚如何解析这个json文件[关闭]
【发布时间】:2020-08-19 10:08:51
【问题描述】:

我刚开始学围棋。

这是我需要解析的文件:

{ 
    "people": {
        "asd": {
            "name": "Alex",
            "id": 0,
            "s": "m"
        },
        "fda": {
            "name": "Mike",
            "id": 1,
            "s": "m"
        },
        "fg2": {
            "name": "Rosa",
            "id": 3,
            "s": "f",
            "Childs" :
            [
                {
                    "name": "Bob",
                    "age": 1,
                    "s": "m"
                },
                {
                    "name": "Maria",
                    "age": 2,
                    "s": "f"
                }
            ]
        }
    }
}

asd、fda、fg2 是由一组随机字符组成的某种标识符。

首先,我无法描述这个文件的结构,我被这些随机标识符弄糊涂了。

我这样做了:

type people {
    People *map[string]interface{} `json:"people"`
}

所以我试图读取和解析这个文件,结果卡住了。 这是我的代码:

package main

import "encoding/json"
import "io/ioutil"
import "log"
import "fmt"

type people struct {
    People map[string]interface{} `json:"people"`
}

func main() {

    file, err := ioutil.ReadFile("./people.json")
    if err != nil {
        log.Println("error:", err)
    }

    var data people

    err = json.Unmarshal([]byte(file), &data)
    if err != nil {
        log.Println("error:", err)
    }

    //fmt.Println(data.people)//

    fmt.Println(data)
    //  for i := 0; i < len(data); i++ {//here the compiler throws error...
    //    fmt.Println("name: ", data[i].name)//#@!o_0
    //  }
  }

错误是:无效操作:data[i](类型人不支持索引)。

请帮我整理一下,打印出这些人的名字,还有他们孩子的名字。

Alex
Mike
Rosa
    Bob
    Maria

【问题讨论】:

  • 他的编译器抛出的错误比#@!o_0 更具描述性,并且会告诉你那里出了什么问题。 data 可能看起来很奇怪,因为您不需要指向映射的指针,结构本身是可寻址的。
  • @JimB 谢谢,我从结构描述中删除了“ * ”字符。错误是:无效操作:data[i](类型人不支持索引)。请告诉我如何使用这种结构...
  • 你不能迭代 data 或索引它,因为它是一个结构体,只有一个名为 People 的字段。
  • @JimB,你能告诉我如何描述这样一个文件的结构吗?
  • 我不确定你的意思,这里展示的 javascript 是一个对象,它有一个名为 "people" 的字段,所以这个结构可以工作。

标签: json parsing go


【解决方案1】:

使用 json.Decoder 可能是最简单的。您还需要记住,在使用不同键(例如您的示例中的“asd”、“fda”、“fg2”)解码 JSON 映射时,您应该使用映射,但对于固定键(“name”、“id”、 "age") 你应该使用结构体。

这里有一些代码来说明Go Playground

package main

import (
    "encoding/json"
    "fmt"
    "strings"
)

type people struct {
    People map[string]Person `json:"people"`
}

type Person struct {
    Name     string   `json:"name"`
    ID       int      `json:"id,omitempty"`
    Sex      string   `json:"s,omitempty"`
    Age      int      `json:"age,omitempty"`
    Children []Person `json:"Childs,omitempty"`
}

func main() {
    file, err := ioutil.ReadFile("./people.json")
    if err != nil {
        log.Fatalln("error:", err)
    }

    var data people
    if err := json.NewDecoder(strings.NewReader(string(file))).Decode(&data); err == nil {
        fmt.Println(data)
    }
}

【讨论】:

    【解决方案2】:

    你可以这样做。更新:对名称进行排序。

    package main
    
    import (
        "encoding/json"
        "fmt"
        "io/ioutil"
        "log"
        "sort"
    )
    
    type people struct {
        People map[string]interface{} `json:"people"`
    }
    
    type Node struct {
        Name     string
        Space    int
        Children *[]Node
    }
    
    func sortAndPrint(ans []Node) {
        if len(ans) == 0 {
            return
        }
        sort.Slice(ans, func(i, j int) bool {
            return ans[i].Name < ans[j].Name
        })
        for _, node := range ans {
            for i := 0; i < node.Space; i++ {
                fmt.Printf(" ")
            }
            fmt.Println(node.Name)
            sortAndPrint(*node.Children)
        }
    }
    
    func findAllNode(ans *[]Node, people map[string]interface{}, space int) {
        ansChild := make([]Node, 0)
    
        *ans = append(*ans, Node{people["name"].(string), space, &ansChild})
        children, hasChildren := (people["Childs"]).([]interface{})
        if !hasChildren {
            return
        }
        for _, child := range children {
            childMap, ok := child.(map[string]interface{})
            if !ok {
                return
            }
            findAllNode(&ansChild, childMap, space+4)
        }
    }
    
    func main() {
        file, err := ioutil.ReadFile("./people.json")
        if err != nil {
            log.Println("error:", err)
        }
    
        var data people
    
        err = json.Unmarshal([]byte(file), &data)
        if err != nil {
            log.Println("error:", err)
        }
    
        ans := make([]Node, 0)
    
        for _, value := range data.People {
            value2, ok := value.(map[string]interface{})
            if !ok {
                continue
            }
            findAllNode(&ans, value2, 0)
        }
    
        sortAndPrint(ans)
    }
    

    【讨论】:

      猜你喜欢
      • 2013-07-31
      • 1970-01-01
      • 2011-03-25
      • 1970-01-01
      • 2020-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多