JSON

Go解析json字符串中多种类型混合的list

字号+ 作者:H5之家 来源:H5之家 2015-11-19 13:26 我要评论( )

我每天似乎都要写代码来解析json字符串,然后总会遇到一些让人不太舒服的Json数据。其中多种类型混合的Json数据会让人很头疼。假如给定一个json对象列表的不同类

Go解析json字符串中多种类型混合的list

2015-10-13 1 阅读

Go

我每天似乎都要写代码来解析json字符串,然后总会遇到一些让人不太舒服的Json数据。其中多种类型混合的Json数据会让人很头疼。

假如给定一个json对象列表的不同类型(假设人物和地点)。你想将它分解成两个列表。一个列表的所有人,和所有地方的列表。

我们先看下Json数据:

{ "things": [ { "name": "Alice", "age": 37 }, { "city": "Ipoh", "country": "Malaysia" }, { "name": "Bob", "age": 36 }, { "city": "Northampton", "country": "England" } ] }

我们需要自己写自定义一个函数:

func solution(jsonString []byte) ([]Person []Place) {}

还有Struct

type Person struct { Name string Age int } type Place struct { City string Country string } 方法A: map and type assert func solutionA(jsonStr []byte) ([]Person, []Place) { persons := []Person{} places := []Place{} var data map[string][]map[string]interface{} err := json.Unmarshal(jsonStr, &data) if err != nil { fmt.Println(err) return persons, places } for i := range data["things"] { item := data["things"][i] if item["name"] != nil { persons = addPerson(persons, item) } else { places = addPlace(places, item) } } return persons, places } func addPerson(persons []Person, item map[string]interface{}) []Person { name, _ := item["name"].(string) age, _ := item["age"].(int) person := Person{name, age} persons = append(persons, person) return persons } func addPlace(places []Place, item map[string]interface{}) []Place { city, _ := item["city"].(string) country, _ := item["city"].(string) place := Place{city, country} places = append(places, place) return places } 方法B: Mixed Type struct type Mixed struct { Name string `json:"name"` Age int `json:"age"` City string `json:"city"` Country string `json:"country"` } func solutionB(jsonStr []byte) ([]Person, []Place) { persons := []Person{} places := []Place{} var data map[string][]Mixed err := json.Unmarshal(jsonStr, &data) if err != nil { fmt.Println(err) return persons, places } for i := range data["things"] { item := data["things"][i] if item.Name != "" { persons = append(persons, Person{item.Name, item.Age}) } else { places = append(places, Place{item.City, item.Country}) } } return persons, places } 方法C: json.RawMessage func solutionC(jsonStr []byte) ([]Person, []Place) { people := []Person{} places := []Place{} var data map[string][]json.RawMessage err := json.Unmarshal(jsonStr, &data) if err != nil { fmt.Println(err) return people, places } for _, thing := range data["things"] { people = addPersonC(thing, people) places = addPlaceC(thing, places) } return people, places } func addPersonC(thing json.RawMessage, people []Person) []Person { person := Person{} if err := json.Unmarshal(thing, &person); err != nil { fmt.Println(err) } else { if person != *new(Person) { people = append(people, person) } } return people } func addPlaceC(thing json.RawMessage, places []Place) []Place { place := Place{} if err := json.Unmarshal(thing, &place); err != nil { fmt.Println(err) } else { if place != *new(Place) { places = append(places, place) } } return places }

我们可以在main方法中测试一下:

package main import ( "encoding/json" "fmt" ) var jsonStr = []byte(` { "things": [ { "name": "Alice", "age": 37 }, { "city": "Ipoh", "country": "Malaysia" }, { "name": "Bob", "age": 36 }, { "city": "Northampton", "country": "England" } ] }`) func main() { personsA, placesA := solutionA(jsonStr) fmt.Printf("%d %d\n", len(personsA), len(placesA)) personsB, placesB := solutionB(jsonStr) fmt.Printf("%d %d\n", len(personsB), len(placesB)) personsC, placesC := solutionC(jsonStr) fmt.Printf("%d %d\n", len(personsC), len(placesC)) } //Common to both solutions type Person struct { Name string Age int } type Place struct { City string Country string } //Solution A //Unmarshal into a map //Type assert when we need it func solutionA(jsonStr []byte) ([]Person, []Place) { persons := []Person{} places := []Place{} var data map[string][]map[string]interface{} err := json.Unmarshal(jsonStr, &data) if err != nil { fmt.Println(err) return persons, places } for i := range data["things"] { item := data["things"][i] if item["name"] != nil { persons = addPerson(persons, item) } else { places = addPlace(places, item) } } return persons, places } func addPerson(persons []Person, item map[string]interface{}) []Person { name, _ := item["name"].(string) age, _ := item["age"].(int) person := Person{name, age} persons = append(persons, person) return persons } func addPlace(places []Place, item map[string]interface{}) []Place { city, _ := item["city"].(string) country, _ := item["city"].(string) place := Place{city, country} places = append(places, place) return places } //SolutionB type Mixed struct { Name string `json:"name"` Age int `json:"age"` City string `json:"city"` Country string `json:"country"` } func solutionB(jsonStr []byte) ([]Person, []Place) { persons := []Person{} places := []Place{} var data map[string][]Mixed err := json.Unmarshal(jsonStr, &data) if err != nil { fmt.Println(err) return persons, places } for i := range data["things"] { item := data["things"][i] if item.Name != "" { persons = append(persons, Person{item.Name, item.Age}) } else { places = append(places, Place{item.City, item.Country}) } } return persons, places } //SolutionC func solutionC(jsonStr []byte) ([]Person, []Place) { people := []Person{} places := []Place{} var data map[string][]json.RawMessage err := json.Unmarshal(jsonStr, &data) if err != nil { fmt.Println(err) return people, places } for _, thing := range data["things"] { people = addPersonC(thing, people) places = addPlaceC(thing, places) } return people, places } func addPersonC(thing json.RawMessage, people []Person) []Person { person := Person{} if err := json.Unmarshal(thing, &person); err != nil { fmt.Println(err) } else { if person != *new(Person) { people = append(people, person) } } return people } func addPlaceC(thing json.RawMessage, places []Place) []Place { place := Place{} if err := json.Unmarshal(thing, &place); err != nil { fmt.Println(err) } else { if place != *new(Place) { places = append(places, place) } } return places }

Go解析json字符串中多种类型混合的list

Go

作者:

谢权'blog

Give Me Freedom,Give Me Fire ,Give Me Reason .Take Me Higher

原文地址:Go解析json字符串中多种类型混合的list, 感谢原作者分享。

→nginx日志格式的自定义和配置 ←YahooNewsOnboarding 仿雅虎新闻引导页面效果

发表评论

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • JSON和XML:不可同日而语

    JSON和XML:不可同日而语

    2016-01-21 16:14

  • 请教golang关于复杂json的解析

    请教golang关于复杂json的解析

    2016-01-17 16:09

  • 对Json进行处理的Google Gson API教程

    对Json进行处理的Google Gson API教程

    2015-11-23 15:47

  • golang的json操作

    golang的json操作

    2015-11-22 10:36

网友点评