check desired json key (not value) exist in the parsed json response in golang

huangapple go评论74阅读模式
英文:

check desired json key (not value) exist in the parsed json response in golang

问题

假设我有一个像这样的 JSON 响应,你可以看到有时存在 email,有时不存在。现在我需要检查 email 键是否存在,并根据情况漂亮地打印 JSON 响应。我该如何做到这一点?

[
  {"name" : "name1", "mobile":"123", "email":"email1@example.com", "carrier":"carrier1", "city", "city1"},
  {"name" : "name2", "mobile":"1234", "carrier":"carrier2", "city", "city2"}
  ...
]

在这里,我需要检查 p.Email 是否存在,如果存在,则赋值为 email 的值,如果不存在,则赋值为空字符串。

for i, p := range jsonbody.Data {
    a := p.Name
    b := p.Phone[i].Mobile
    c := ""
    if p.Email != nil {
        c = *p.Email
    }
    d := p.Phone[i].Carrier
    e := p.Address[i].City
    // 其他操作
}

我尝试搜索,但没有找到关于 Golang 的答案。

英文:

lets say i have a json response like this, as you can see sometimes email exists sometimes not.
now i need to check the email key exists or not and pretty print the json response accordingly.
how can i do this?

[
  {"name" : "name1", "mobile": "123", "email": "email1@example.com", "carrier": "carrier1", "city", "city1"},
  {"name" : "name2", "mobile": "1234", "carrier": "carrier2", "city", "city2"}
  ...
]

here i need to check the p.Email exists or not, if it exists assign the email value if not assign empty string

for i, p := range jsonbody.Data {
						
						a := p.Name
						b := p.Phone[i].Mobile
						c := p.INTaddress[i].Email  // here i need to check 
						d := p.Phone[i].Carrier
						e := p.Address[i].City
                          
                         ..........

}
						

i tried searching but not found any answers for golang.

答案1

得分: 1

在这里,我需要检查p.Email是否存在,如果存在,则赋值为email的值;如果不存在,则赋值为空字符串。

请注意,当您将字段定义为Email string,并且传入的JSON不提供"email"条目时,Email字段将保持为空字符串,因此您可以直接使用它。不需要额外的检查。

如果您想允许null,请使用Email *string,并使用if条件检查nil,如072的答案所建议的那样。

当您需要区分未定义/空/空值时,可以使用下面答案中建议的自定义解组器:

type String struct {
	IsDefined bool
	Value     string
}

// 此方法将自动由json.Unmarshal调用
// 但仅适用于在json中提供的值,无论它们是否为null。
func (s *String) UnmarshalJSON(d []byte) error {
	s.IsDefined = true
	if string(d) != "null" {
		return json.Unmarshal(d, &s.Value)
	}
	return nil
}

然后,您可以在需要检查是否提供了字段的地方使用自定义的String,并且在解组发生后,您显然会检查IsDefined字段。

英文:

> here i need to check the p.Email exists or not, if it exists assign the email value if not assign empty string

Note that when you define the field as Email string and the incoming JSON provides no "email" entry then the Email field will remain an empty string, so you could simply use that as is. No additional checks necessary.

If you want to allow for null use Email *string and simply use an if condition to check against nil as suggested by 072's answer.

And when you need to differentiate between undefined/null/empty use a custom unmarshaler as suggested in the answer below:

type String struct {
	IsDefined bool
	Value     string
}

// This method will be automatically invoked by json.Unmarshal
// but only for values that were provided in the json, regardless
// of whether they were null or not.
func (s *String) UnmarshalJSON(d []byte) error {
	s.IsDefined = true
	if string(d) != "null" {
		return json.Unmarshal(d, &s.Value)
	}
	return nil
}

https://go.dev/play/p/gs9G4v32HWL

Then you can use the custom String instead of the builtin string for the fields that you need to check whether they were provided or not. And to do the checking, you'd obviously inspect the IsDefined field after the unmarshal happened.

答案2

得分: 0

你可以使用指针,然后检查是否为nil

package main

import (
   "encoding/json"
   "fmt"
)

var input = []byte(`
[
  {"name" : "name1", "mobile":"123", "email":"email1@example.com", "carrier":"carrier1", "city":"city1"},
  {"name" : "name2", "mobile":"1234", "carrier":"carrier2", "city":"city2"}
]
`)

type contact struct {
   Name string
   Email *string
}

func main() {
   var contacts []contact
   json.Unmarshal(input, &contacts)
   // [{Name:name1 Email:0xc00004a340} {Name:name2 Email:<nil>}]
   fmt.Printf("%+v\n", contacts)
}
英文:

You can use a pointer, then check against nil:

package main

import (
   &quot;encoding/json&quot;
   &quot;fmt&quot;
)

var input = []byte(`
[
  {&quot;name&quot; : &quot;name1&quot;, &quot;mobile&quot;: &quot;123&quot;, &quot;email&quot;: &quot;email1@example.com&quot;, &quot;carrier&quot;: &quot;carrier1&quot;, &quot;city&quot;: &quot;city1&quot;},
  {&quot;name&quot; : &quot;name2&quot;, &quot;mobile&quot;: &quot;1234&quot;, &quot;carrier&quot;: &quot;carrier2&quot;, &quot;city&quot;: &quot;city2&quot;}
]
`)

type contact struct {
   Name string
   Email *string
}

func main() {
   var contacts []contact
   json.Unmarshal(input, &amp;contacts)
   // [{Name:name1 Email:0xc00004a340} {Name:name2 Email:&lt;nil&gt;}]
   fmt.Printf(&quot;%+v\n&quot;, contacts)
}

<!--
433pm
433pm
-->

huangapple
  • 本文由 发表于 2022年10月9日 22:04:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/74005452.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定