package main
import (
"fmt"
"reflect"
"encoding/json"
)
func main() {
/*
* Encode Decode arbitrary map and JSON
*/
orderMap := map[string]interface{}{
"status": true,
"name": "bot",
"age": 18,
//"itemArr": []map[string]interface{}{},
"itemArr": []interface{}{},
}
orderMap["email"] = "bot@example.com"
item0 := map[string]interface{}{
"lineNum": 0,
"itemNum": "A0",
"itemPrice": 90,
}
item1 := map[string]interface{}{
"lineNum": 1,
"itemNum": "A1",
"itemPrice": 91,
"accessoryArr": []interface{}{},
}
item1["accessoryArr"] = append(item1["accessoryArr"].([]interface{}), map[string]interface{}{"name": "bag", "price": 10})
item1["accessoryArr"] = append(item1["accessoryArr"].([]interface{}), map[string]interface{}{"name": "tray", "price": 12})
// To access the element we can use a type assertion to access the underlying map of the orderMap["itemArr"].
orderMap["itemArr"] = append(orderMap["itemArr"].([]interface{}), item0)
orderMap["itemArr"] = append(orderMap["itemArr"].([]interface{}), item1)
orderJson, err := json.Marshal(orderMap)
if err == nil {
itemArrType := reflect.TypeOf(orderMap["itemArr"])
itemArrTypeKind := reflect.TypeOf(orderMap["itemArr"]).Kind()
itemArrElemType := reflect.TypeOf(orderMap["itemArr"]).Elem()
fmt.Printf("itemArr: %v\n", itemArrType)
fmt.Printf("itemArrTypeKind: %v\n", itemArrTypeKind)
fmt.Printf("itemElement: %v\n", itemArrElemType)
fmt.Printf("\n")
fmt.Println("=== Showing the original orderMap:")
fmt.Printf("%v\n\n", orderMap)
fmt.Println("=== Showing the encoded orderJson:")
fmt.Printf("%v\n\n", string(orderJson))
fmt.Println("=== Showing the decoded orderJson:")
// As we're un-marshalling into an interface, we need to inform go what data type each key is before we can perform operations on it.
// This is what the .(map[string]interface{}) does
var orderMapTmp map[string]interface{}
json.Unmarshal([]byte(orderJson), &orderMapTmp)
fmt.Printf("%v\n\n", orderMapTmp)
fmt.Println("=== Showing how to access individual element in the decoded orderJson:")
// The data type here was the key. [0] was not actually a map, but an interface{}, which could be anything - a map, a string, an int. You need to "type assertion" it to a map first, or do the awkward case switch outlined in JSON and Go.
// Otherwise, you will get "invalid operation: type interface {} does not support indexing)".
fmt.Printf("itemNum: %v\n", orderMapTmp["itemArr"].([]interface{})[0].(map[string]interface{})["itemNum"])
fmt.Printf("itemPrice: %v\n", orderMapTmp["itemArr"].([]interface{})[0].(map[string]interface{})["itemPrice"])
}
}
Output:
itemArr: []interface {}
itemArrTypeKind: slice
itemElement: interface {}
=== Showing the original orderMap:
map[status:true name:bot age:18 itemArr:[map[lineNum:0 itemNum:A0 itemPrice:90] map[itemPrice:91 accessoryArr:[map[name:bag price:10] map[price:12 name:tray]] lineNum:1 itemNum:A1]] email:bot@example.com]
=== Showing the encoded orderJson:
{"age":18,"email":"bot@example.com","itemArr":[{"itemNum":"A0","itemPrice":90,"lineNum":0},{"accessoryArr":[{"name":"bag","price":10},{"name":"tray","price":12}],"itemNum":"A1","itemPrice":91,"lineNum":1}],"name":"bot","status":true}
=== Showing the decoded orderJson:
map[status:true age:18 email:bot@example.com itemArr:[map[itemNum:A0 itemPrice:90 lineNum:0] map[accessoryArr:[map[name:bag price:10] map[name:tray price:12]] itemNum:A1 itemPrice:91 lineNum:1]] name:bot]
=== Showing how to access individual element in the decoded orderJson:
itemNum: A0
itemPrice: 90
Reference:
https://michaelheap.com/golang-encodedecode-arbitrary-json/
http://stackoverflow.com/questions/25214036/getting-invalid-operation-mymaptitle-type-interface-does-not-support-in
No comments:
Post a Comment