如何在将 json 解组为结构时过滤掉重复项?
How to filter out duplicates while unmarshalling json into struct?
我有这个 json,我正在尝试将其解组到我的结构中。
{
"clientMetrics": [
{
"clientId": 951231,
"customerData": {
"Process": [
"ABC"
],
"Mat": [
"KKK"
]
},
"legCustomer": [
8773
]
},
{
"clientId": 1234,
"legCustomer": [
8789
]
},
{
"clientId": 3435,
"otherIds": [
4,
32,
19
],
"legCustomer": [
10005
]
},
{
"clientId": 9981,
"catId": 8,
"legCustomer": [
13769
]
},
{
"clientId": 12124,
"otherIds": [
33,
29
],
"legCustomer": [
12815
]
},
{
"clientId": 8712,
"customerData": {
"Process": [
"College"
]
},
"legCustomer": [
951
]
},
{
"clientId": 23214,
"legCustomer": [
12724,
12727
]
},
{
"clientId": 119812,
"catId": 8,
"legCustomer": [
14519
]
},
{
"clientId": 22315,
"otherIds": [
32
],
"legCustomer": [
12725,
13993
]
},
{
"clientId": 765121,
"catId": 8,
"legCustomer": [
14523
]
}
]
}
我用这个tool生成结构如下所示-
type AutoGenerated struct {
ClientMetrics []ClientMetrics `json:"clientMetrics"`
}
type CustomerData struct {
Process []string `json:"Process"`
Mat []string `json:"Mat"`
}
type ClientMetrics struct {
ClientID int `json:"clientId"`
CustomerData CustomerData `json:"customerData,omitempty"`
LegCustomer []int `json:"legCustomer"`
OtherIds []int `json:"otherIds,omitempty"`
CatID int `json:"catId,omitempty"`
CustomerData CustomerData `json:"customerData,omitempty"`
}
现在我的困惑是,我有很多字符串或整数数组,那么如何过滤掉重复项?我相信 golang 中没有设置数据类型,所以我怎么能在这里实现同样的事情呢?基本上,当我将 json 解组到我的结构中时,我需要确保根本不存在重复项。有什么办法可以做到这一点?如果是,有人可以提供一个示例,说明如何为我的上述 json 实现这一点,以及我应该如何为此设计我的结构。
更新
所以基本上只是像这样使用并更改我的结构定义,仅此而已?在内部它会调用 UnmarshalJSON
并处理重复项?我会将 json 字符串和结构传递给 JSONStringToStructure
方法。
func JSONStringToStructure(jsonString string, structure interface{}) error {
jsonBytes := []byte(jsonString)
return json.Unmarshal(jsonBytes, structure)
}
type UniqueStrings []string
func (u *UniqueStrings) UnmarshalJSON(in []byte) error {
var arr []string
if err := json.Unmarshal(in, arr); err != nil {
return err
}
*u = UniqueStrings(dedupStr(arr))
return nil
}
func dedupStr(in []string) []string {
seen:=make(map[string]struct{})
w:=0
for i:=range in {
if _,s:=seen[in[i]]; !s {
seen[in[i]]=struct{}{}
in[w]=in[i]
w++
}
}
return in[:w]
}
理想情况下,您应该 post 处理这些数组以删除重复项。但是,您可以在使用带有解组器的自定义类型进行解组期间实现此目的:
type UniqueStrings []string
func (u *UniqueStrings) UnmarshalJSON(in []byte) error {
var arr []string
if err:=json.Unmarshal(in,arr); err!=nil {
return err
}
*u=UniqueStrings(dedupStr(arr))
return nil
}
哪里
func dedupStr(in []string) []string {
seen:=make(map[string]struct{})
w:=0
for i:=range in {
if _,s:=seen[in[i]]; !s {
seen[in[i]]=struct{}{}
in[w]=in[i]
w++
}
}
return in[:w]
}
您可以对 []int
s 使用类似的方法。
您在结构中使用自定义类型:
type CustomerData struct {
Process UniqueStrings `json:"Process"`
Mat UniqueStrings `json:"Mat"`
}
我有这个 json,我正在尝试将其解组到我的结构中。
{
"clientMetrics": [
{
"clientId": 951231,
"customerData": {
"Process": [
"ABC"
],
"Mat": [
"KKK"
]
},
"legCustomer": [
8773
]
},
{
"clientId": 1234,
"legCustomer": [
8789
]
},
{
"clientId": 3435,
"otherIds": [
4,
32,
19
],
"legCustomer": [
10005
]
},
{
"clientId": 9981,
"catId": 8,
"legCustomer": [
13769
]
},
{
"clientId": 12124,
"otherIds": [
33,
29
],
"legCustomer": [
12815
]
},
{
"clientId": 8712,
"customerData": {
"Process": [
"College"
]
},
"legCustomer": [
951
]
},
{
"clientId": 23214,
"legCustomer": [
12724,
12727
]
},
{
"clientId": 119812,
"catId": 8,
"legCustomer": [
14519
]
},
{
"clientId": 22315,
"otherIds": [
32
],
"legCustomer": [
12725,
13993
]
},
{
"clientId": 765121,
"catId": 8,
"legCustomer": [
14523
]
}
]
}
我用这个tool生成结构如下所示-
type AutoGenerated struct {
ClientMetrics []ClientMetrics `json:"clientMetrics"`
}
type CustomerData struct {
Process []string `json:"Process"`
Mat []string `json:"Mat"`
}
type ClientMetrics struct {
ClientID int `json:"clientId"`
CustomerData CustomerData `json:"customerData,omitempty"`
LegCustomer []int `json:"legCustomer"`
OtherIds []int `json:"otherIds,omitempty"`
CatID int `json:"catId,omitempty"`
CustomerData CustomerData `json:"customerData,omitempty"`
}
现在我的困惑是,我有很多字符串或整数数组,那么如何过滤掉重复项?我相信 golang 中没有设置数据类型,所以我怎么能在这里实现同样的事情呢?基本上,当我将 json 解组到我的结构中时,我需要确保根本不存在重复项。有什么办法可以做到这一点?如果是,有人可以提供一个示例,说明如何为我的上述 json 实现这一点,以及我应该如何为此设计我的结构。
更新
所以基本上只是像这样使用并更改我的结构定义,仅此而已?在内部它会调用 UnmarshalJSON
并处理重复项?我会将 json 字符串和结构传递给 JSONStringToStructure
方法。
func JSONStringToStructure(jsonString string, structure interface{}) error {
jsonBytes := []byte(jsonString)
return json.Unmarshal(jsonBytes, structure)
}
type UniqueStrings []string
func (u *UniqueStrings) UnmarshalJSON(in []byte) error {
var arr []string
if err := json.Unmarshal(in, arr); err != nil {
return err
}
*u = UniqueStrings(dedupStr(arr))
return nil
}
func dedupStr(in []string) []string {
seen:=make(map[string]struct{})
w:=0
for i:=range in {
if _,s:=seen[in[i]]; !s {
seen[in[i]]=struct{}{}
in[w]=in[i]
w++
}
}
return in[:w]
}
理想情况下,您应该 post 处理这些数组以删除重复项。但是,您可以在使用带有解组器的自定义类型进行解组期间实现此目的:
type UniqueStrings []string
func (u *UniqueStrings) UnmarshalJSON(in []byte) error {
var arr []string
if err:=json.Unmarshal(in,arr); err!=nil {
return err
}
*u=UniqueStrings(dedupStr(arr))
return nil
}
哪里
func dedupStr(in []string) []string {
seen:=make(map[string]struct{})
w:=0
for i:=range in {
if _,s:=seen[in[i]]; !s {
seen[in[i]]=struct{}{}
in[w]=in[i]
w++
}
}
return in[:w]
}
您可以对 []int
s 使用类似的方法。
您在结构中使用自定义类型:
type CustomerData struct {
Process UniqueStrings `json:"Process"`
Mat UniqueStrings `json:"Mat"`
}