2016-12-06 49 views
2

我正在读取json中的API响应,并且遇到了json值(字符串,null,bool)内有多个数据类型的问题。另外,一些键的值可以是字符串或空值,这使得将数据读入类型变得更加困难。我想将所有内容都转换为字符串以便于处理。我创建了一个基于谷歌搜索其他例子的类型开关。我想知道这是否是最简单的方法,或者我错过了一个更简单的方法。Golang将json的变量类型转换为字符串

package main 

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

func main() { 

json_byte := []byte(`{"response":[{"t_int":1, "t_bool": true, "t_null_or_string": null}, {"t_int":2, "t_bool": false, "t_null_or_string": "string1"}]}`) 

//unmarshal the json to data structure using interface for variable data types 
data_json := make(map[string][]map[string]interface{}) //create a structure to hold unmarshalled json 
if err := json.Unmarshal(json_byte, &data_json); err != nil { 
    panic(err) 
} 
fmt.Println("json_data: ", data_json) 

//Iterate over data structure and convert Bool, Int, and Null types to string 
var v_conv string        // temporary holding for converted string values 
data_map := make(map[string]string)    // temporary holding for converted maps 
data_final := make([]map[string]string, 0, 100) // final holding for data converted to strings 

for _, v := range data_json { //v is the value of the "response": key which is a slice of maps 
    for _, v2 := range v { //v2 is one of the maps in the slice of maps 
     for k3, v3 := range v2 { //k3 and v3 are the keys and values inside the map 
      fmt.Println("k3: ", k3, "v3: ", v3) 
      switch v_type := v3.(type) { 
      case nil: 
       v_conv = "" 
      case bool: 
       v_conv = strconv.FormatBool(v3.(bool)) 
      case int: 
       v_conv = strconv.Itoa(v3.(int)) 
      case string: 
       v_conv = v3.(string) 
      case float64: 
       v_conv = strconv.FormatFloat(v3.(float64), 'f', 0, 64) 
      default: 
       fmt.Println("vtype unknown: ", v_type) //have to use v_type since it is declared 
       v_conv = "" 
      } 
      data_map[k3] = v_conv //append a new map key/value pair both as strings 
      fmt.Println("data_map: ", data_map) 
     } 
     data_final = append(data_final, data_map) // after each cycle through the loop append the map to the new list 
     fmt.Println("data_final: ", data_final) 
    } 
} 
} 

最终格式所期望的地图 [{ “T_INT”: “1”, “t_bool”: “真”, “t_null_string”: “的切片” }, { “T_INT “: “2”, “t_bool”: “假”, “t_null_string”: “字符串1” }]

回答

2

对于这个答案我假设JSON在你的例子是(的一部分)的例子你的JSON输入。 在这种情况下,您的JSON具有特定的结构:您知道哪些属性将与已知的数据类型一起提供,并且您还知道哪些属性是动态的。与混合型

{ 
    Response: 
    [ 
     { 
      TInt:1 
      TBool:true 
      TMixed:<nil> 
     } 
      { 
      TInt:2 
      TBool:false 
      TMixed:string1 
     } 
    ] 
} 

是的,一个属性你会碰到一个: 例如,你可以解组的JSON到水木清华像ResponseObj如下:

package main 

import (
    "encoding/json" 
    "fmt" 
) 

type ResponseObj struct { 
    Response []Item `json:"response"` 
} 

type Item struct { 
    TInt int   `json:"t_int"` 
    TBool bool  `json:"t_bool"` 
    TMixed interface{} `json:"t_null_or_string"` 
} 

func main() { 

    json_byte := []byte(`{"response":[{"t_int":1, "t_bool": true, "t_null_or_string": null}, {"t_int":2, "t_bool": false, "t_null_or_string": "string1"}]}`) 

    data_json := ResponseObj{} 
    if err := json.Unmarshal(json_byte, &data_json); err != nil { 
     panic(err) 
    } 
    fmt.Printf("%+v\n", data_json) 
} 

你的数据会看起来像键入assertion(或者与nil比较,或者两者都是)。

不太可能你的JSON是一个不可预测类型的混乱。很可能,您可以选择一个核心结构,并使用interface {}来获取剩余的混合类型。

希望这会有所帮助。

+0

我会说这是他的情况下最好的解决方案。 –

+0

是的,那更干净。谢谢。 –