Skip to content

Commit e4fc67c

Browse files
committed
Added group modifier
The new "@group" modifier allows for grouping arrays of objects. For example, using the "@group" modifier on the following json... {"id":["123","456","789"],"val":[2,1]} will results in... [{"id":"123","val":2},{"id":"456","val":1},{"id":"789"}]
1 parent f47e17d commit e4fc67c

File tree

2 files changed

+72
-0
lines changed

2 files changed

+72
-0
lines changed

gjson.go

+36
Original file line numberDiff line numberDiff line change
@@ -2671,6 +2671,7 @@ var modifiers = map[string]func(json, arg string) string{
26712671
"values": modValues,
26722672
"tostr": modToStr,
26732673
"fromstr": modFromStr,
2674+
"group": modGroup,
26742675
}
26752676

26762677
// AddModifier binds a custom modifier command to the GJSON syntax.
@@ -2972,6 +2973,41 @@ func modToStr(str, arg string) string {
29722973
return string(data)
29732974
}
29742975

2976+
func modGroup(json, arg string) string {
2977+
res := Parse(json)
2978+
if !res.IsObject() {
2979+
return ""
2980+
}
2981+
var all [][]byte
2982+
res.ForEach(func(key, value Result) bool {
2983+
if !value.IsArray() {
2984+
return true
2985+
}
2986+
var idx int
2987+
value.ForEach(func(_, value Result) bool {
2988+
if idx == len(all) {
2989+
all = append(all, []byte{})
2990+
}
2991+
all[idx] = append(all[idx], ("," + key.Raw + ":" + value.Raw)...)
2992+
idx++
2993+
return true
2994+
})
2995+
return true
2996+
})
2997+
var data []byte
2998+
data = append(data, '[')
2999+
for i, item := range all {
3000+
if i > 0 {
3001+
data = append(data, ',')
3002+
}
3003+
data = append(data, '{')
3004+
data = append(data, item[1:]...)
3005+
data = append(data, '}')
3006+
}
3007+
data = append(data, ']')
3008+
return string(data)
3009+
}
3010+
29753011
// stringHeader instead of reflect.StringHeader
29763012
type stringHeader struct {
29773013
data unsafe.Pointer

gjson_test.go

+36
Original file line numberDiff line numberDiff line change
@@ -2467,3 +2467,39 @@ func TestToFromStr(t *testing.T) {
24672467
res := Get(json, "[email protected].#.eventVersion.@tostr").Raw
24682468
assert(t, res == `["\"2.1\""]`)
24692469
}
2470+
2471+
func TestGroup(t *testing.T) {
2472+
json := `{"id":["123","456","789"],"val":[2,1]}`
2473+
res := Get(json, "@group").Raw
2474+
assert(t, res == `[{"id":"123","val":2},{"id":"456","val":1},{"id":"789"}]`)
2475+
2476+
json = `
2477+
{
2478+
"issues": [
2479+
{
2480+
"fields": {
2481+
"labels": [
2482+
"milestone_1",
2483+
"group:foo",
2484+
"plan:a",
2485+
"plan:b"
2486+
]
2487+
},
2488+
"id": "123"
2489+
},{
2490+
"fields": {
2491+
"labels": [
2492+
"milestone_1",
2493+
"group:foo",
2494+
"plan:a",
2495+
"plan"
2496+
]
2497+
},
2498+
"id": "456"
2499+
}
2500+
]
2501+
}
2502+
`
2503+
res = Get(json, `{"id":issues.#.id,"plans":issues.#.fields.labels.#(%"plan:*")#|#.#}|@group|#(plans>=2)#.id`).Raw
2504+
assert(t, res == `["123"]`)
2505+
}

0 commit comments

Comments
 (0)