gjson
gjson copied to clipboard
Support "@unique" modifier
I understand that this modifier can be easily done by anyone, but suppose that it migth be needed not only by me and it would be clearer to use from lib.
I suggest to add modifier @unique , if it would be not so hard.
gjson.AddModifier("unique", func(_json, arg string) string {
var arr []string
_ = json.Unmarshal([]byte(_json), &arr)
keys := make(map[string]bool)
var list []string
for _, entry := range arr {
if _, value := keys[entry]; !value {
keys[entry] = true
list = append(list, entry)
}
}
data, _ := json.Marshal(list)
return string(data)
})
I Understand that there might be a lot of different cases , not only flat slice of strings.
I needed to extract uniq user_ids and count them, so I would provide my case here as example:
json_bytes := []byte(`{
"agreements": [
{"a_id":"1111", "policies":[
{"id":"1", "insured_id":"123"},
{"id":"2", "insured_id":"222"},
{"id":"3", "insured_id":"333"},
]},
{"a_id":"2222", "policies":[
{"id":"4", "insured_id":"444"},
{"id":"5", "insured_id":"222"},
{"id":"6", "insured_id":"666"},
]},
]
}`)
gjson.AddModifier("unique", func(_json, arg string) string {
var arr []string
_ = json.Unmarshal([]byte(_json), &arr)
keys := make(map[string]bool)
var list []string
for _, entry := range arr {
if _, value := keys[entry]; !value {
keys[entry] = true
list = append(list, entry)
}
}
data, _ := json.Marshal(list)
return string(data)
})
value := gjson.Get(string(json_bytes), "agreements.#.policies.#.insured_id|@flatten|@unique.#")
println("result:",value.String())
result: 5
can discuss here and i can prepare PR
Unique is useful, but i don't think that you need to unmarshal json, you can parse it with gjson, will be faster