代码之家  ›  专栏  ›  技术社区  ›  sbaildon

解组数组中的单个元素

  •  -1
  • sbaildon  · 技术社区  · 6 年前

    有没有办法在Go中将JSON数组解组为单个对象?

    我有一个来自端点的json响应:

    {
      "results": [
        {
            "key": "value"
        }
      ]
    }
    

    数组中的对象有一个Go结构:

    type Object struct {
        Key string `json:"key"`
    }
    

    。。。以及响应对象的结构:

    type Response struct {
        Objects []Object `json:"results"`
    }
    

    results 是一个对象数组,但我知道端点将只返回一个包含1个对象的数组。有没有办法取消对数据的编组,避免通过索引引用对象?我希望我可以用 json:"results[0]" 作为字段标记。

    我希望能够:

    decoder.Decode(&response)
    response.Object.Key
    

    而不是

    decoder.Decode(&response)
    response.Objects[0].Key
    
    2 回复  |  直到 6 年前
        1
  •  2
  •   Aristofanio Garcia    6 年前

    为此,需要自定义解组。 一种方法是创建如下响应:

    //Response json (customized) that match with Unmarshaler interface
    type ResponseCustom struct {
        Object
    }
    
    func (r *ResponseCustom) UnmarshalJSON(b []byte) error{
        rsp := &Response{}
        err := json.Unmarshal(b, rsp)
        if err != nil {
            log.Fatalln("error:", err)
        } else {
            r.Object = rsp.Objects[0]
        }
        //
        return err
    }
    

    因此,可以使用ResponseCustom而不是Response来获取对象值。 外观:

    func main() {
        //
        data := []byte(jsondata)
        resp := &ResponseCustom{}
        //
        json.Unmarshal(data, resp)
        //
        fmt.Println("My Object.value is: " + resp.Object.Key)
    }
    

    结果是:

        My Object.value is: value
    

    在操场上: https://play.golang.org/p/zo7wOSacA4w

        2
  •  0
  •   Himanshu    6 年前

    实现解组器接口,将对象数组转换为对象。获取key的值,然后将json解组为

    package main
    
    import(
      "fmt"
      "encoding/json"
    )
    
    type Object struct {
      Key string `json:"key"`
    }
    
    func (obj *Object) UnmarshalJSON(data []byte) error {
      var v map[string]interface{}
      if err := json.Unmarshal(data, &v); err != nil {
          fmt.Printf("Error whilde decoding %v\n", err)
          return err
      }
      obj.Key =  v["results"].(interface{}).([]interface{})[0].(interface{}).(map[string]interface{})["key"].(interface{}).(string)
      return nil
    }
    
    
    func main(){
      var obj Object
      data := []byte(`{
        "results": [
          {
              "key": "value"
          }
        ]
      }`)
      if err := json.Unmarshal(data, &obj); err!=nil{
        fmt.Println(err)
      }
      fmt.Printf("%#v", obj) 
    }
    

    Playground