解组不带结构的未知JSON字段

时间:2019-07-06 08:37:18

标签: go

我正在尝试解组具有可选数组的JSON对象,我在没有数组的情况下执行此操作,这是到目前为止我得到的:

const myQuery = gql`
  query {
    users {
      id
      name
      pet {
        id
        name
      }
    }
  }
`;

// Inside Render function if using React ...
return users.map(({ id, name, pet }) => (
        <div key={id}>
          <ul>
            <li>
              {id} {name}
              {Object.values({ pet })[0].name}
            </li>
          </ul>
        </div>
      ));

import ( "encoding/json" "fmt" ) func main() { jo := ` { "given_name": "Akshay Raj", "name": "Akshay", "country": "New Zealand", "family_name": "Gollahalli", "emails": [ "name@example.com" ] } ` var raw map[string]interface{} err := json.Unmarshal([]byte(jo), &raw) if err != nil { panic(err) } fmt.Println(raw["emails"][0]) } 字段有时会出现也可能不会出现。我知道我可以使用emails并将其解组两次,无论是否使用数组。当我尝试获取struct的索引0时,出现以下错误

raw["emails"][0]

是否可以获取invalid operation: raw["emails"][0] (type interface {} does not support indexing) 字段的索引?

更新1

我可以执行类似emails的操作,并且可以正常工作。这是唯一的方法吗?

3 个答案:

答案 0 :(得分:4)

最简单的方法是使用结构。无需解组两次。

type MyStruct struct {
    // ... other fields
    Emails []string `json:"emails"`
}

无论JSON输入是否包含emails字段,这都将起作用。如果缺少它,则生成的结构将只具有未初始化的Emails字段。

答案 1 :(得分:1)

您可以使用类型断言。有关类型断言的Go教程为here

将类型断言应用于您的问题的“转到游乐场”链接为here。为了便于阅读,该代码复制如下:

package main

import (
    "encoding/json"
    "fmt"
)

func main() {
    jo := `
        {
            "given_name": "Akshay Raj",
            "name": "Akshay",
            "country": "New Zealand",
            "family_name": "Gollahalli",
            "emails": [
                "name@example.com"
            ]
        }
        `
    var raw map[string]interface{}
    err := json.Unmarshal([]byte(jo), &raw)
    if err != nil {
        panic(err)
    }

    emails, ok := raw["emails"]
    if !ok {
        panic("do this when no 'emails' key")
    }

    emailsSlice, ok := emails.([]interface{})
    if !ok {
        panic("do this when 'emails' value is not a slice")
    }

    if len(emailsSlice) == 0 {
        panic("do this when 'emails' slice is empty")
    }

    email, ok := (emailsSlice[0]).(string)
    if !ok {
        panic("do this when 'emails' slice contains non-string")
    }

    fmt.Println(email)

}

答案 2 :(得分:0)

与往常一样,您可以使用其他库来处理json数据。例如,使用gojsonq软件包,它将像这样:

package main

import (
    "fmt"

    "github.com/thedevsaddam/gojsonq"
)

func main() {

    json := `
        {
            "given_name": "Akshay Raj",
            "name": "Akshay",
            "country": "New Zealand",
            "family_name": "Gollahalli",
            "emails": [
                "name@example.com"
                ]
        }
        `
    first := gojsonq.New().JSONString(json).Find("emails.[0]")
    if first != nil {
        fmt.Println(first.(string))
    } else {
        fmt.Println("There isn't emails")
    }

}