forked from mirror/gjson
Added @keys and @values modifiers
The "@keys" and "@values" modifiers converts an object into an array of its keys or values respectively. Take this json for example: {"first":"Tom","last":"Smith"} @keys -> ["first","last"] @values -> ["Tom","Smith"] This feature was requested in #161.
This commit is contained in:
parent
4fe1916c56
commit
35fa0d71c8
|
@ -200,6 +200,8 @@ There are currently the following built-in modifiers:
|
|||
- `@valid`: Ensure the json document is valid.
|
||||
- `@flatten`: Flattens an array.
|
||||
- `@join`: Joins multiple objects into a single object.
|
||||
- `@keys`: Returns an array of keys for an object.
|
||||
- `@values`: Returns an array of values for an object.
|
||||
|
||||
### Modifier arguments
|
||||
|
||||
|
|
|
@ -236,6 +236,8 @@ There are currently the following built-in modifiers:
|
|||
- `@valid`: Ensure the json document is valid.
|
||||
- `@flatten`: Flattens an array.
|
||||
- `@join`: Joins multiple objects into a single object.
|
||||
- `@keys`: Returns an array of keys for an object.
|
||||
- `@values`: Returns an array of values for an object.
|
||||
|
||||
#### Modifier arguments
|
||||
|
||||
|
|
54
gjson.go
54
gjson.go
|
@ -2565,6 +2565,8 @@ var modifiers = map[string]func(json, arg string) string{
|
|||
"flatten": modFlatten,
|
||||
"join": modJoin,
|
||||
"valid": modValid,
|
||||
"keys": modKeys,
|
||||
"values": modValues,
|
||||
}
|
||||
|
||||
// AddModifier binds a custom modifier command to the GJSON syntax.
|
||||
|
@ -2721,6 +2723,58 @@ func modFlatten(json, arg string) string {
|
|||
return bytesString(out)
|
||||
}
|
||||
|
||||
// @keys extracts the keys from an object.
|
||||
// {"first":"Tom","last":"Smith"} -> ["first","last"]
|
||||
func modKeys(json, arg string) string {
|
||||
v := Parse(json)
|
||||
if !v.Exists() {
|
||||
return "[]"
|
||||
}
|
||||
obj := v.IsObject()
|
||||
var out strings.Builder
|
||||
out.WriteByte('[')
|
||||
var i int
|
||||
v.ForEach(func(key, _ Result) bool {
|
||||
if i > 0 {
|
||||
out.WriteByte(',')
|
||||
}
|
||||
if obj {
|
||||
out.WriteString(key.Raw)
|
||||
} else {
|
||||
out.WriteString("null")
|
||||
}
|
||||
i++
|
||||
return true
|
||||
})
|
||||
out.WriteByte(']')
|
||||
return out.String()
|
||||
}
|
||||
|
||||
// @values extracts the values from an object.
|
||||
// {"first":"Tom","last":"Smith"} -> ["Tom","Smith"]
|
||||
func modValues(json, arg string) string {
|
||||
v := Parse(json)
|
||||
if !v.Exists() {
|
||||
return "[]"
|
||||
}
|
||||
if v.IsArray() {
|
||||
return json
|
||||
}
|
||||
var out strings.Builder
|
||||
out.WriteByte('[')
|
||||
var i int
|
||||
v.ForEach(func(_, value Result) bool {
|
||||
if i > 0 {
|
||||
out.WriteByte(',')
|
||||
}
|
||||
out.WriteString(value.Raw)
|
||||
i++
|
||||
return true
|
||||
})
|
||||
out.WriteByte(']')
|
||||
return out.String()
|
||||
}
|
||||
|
||||
// @join multiple objects into a single object.
|
||||
// [{"first":"Tom"},{"last":"Smith"}] -> {"first","Tom","last":"Smith"}
|
||||
// The arg can be "true" to specify that duplicate keys should be preserved.
|
||||
|
|
|
@ -2207,3 +2207,31 @@ func TestIssue240(t *testing.T) {
|
|||
parsed = Parse(arrayData)
|
||||
assert(t, len(parsed.Get("params.data").Array()) == 1)
|
||||
}
|
||||
|
||||
func TestKeysValuesModifier(t *testing.T) {
|
||||
var json = `{
|
||||
"1300014": {
|
||||
"code": "1300014",
|
||||
"price": 59.18,
|
||||
"symbol": "300014",
|
||||
"update": "2020/04/15 15:59:54",
|
||||
},
|
||||
"1300015": {
|
||||
"code": "1300015",
|
||||
"price": 43.31,
|
||||
"symbol": "300015",
|
||||
"update": "2020/04/15 15:59:54",
|
||||
}
|
||||
}`
|
||||
assert(t, Get(json, `@keys`).String() == `["1300014","1300015"]`)
|
||||
assert(t, Get(``, `@keys`).String() == `[]`)
|
||||
assert(t, Get(`"hello"`, `@keys`).String() == `[null]`)
|
||||
assert(t, Get(`[]`, `@keys`).String() == `[]`)
|
||||
assert(t, Get(`[1,2,3]`, `@keys`).String() == `[null,null,null]`)
|
||||
|
||||
assert(t, Get(json, `@values.#.code`).String() == `["1300014","1300015"]`)
|
||||
assert(t, Get(``, `@values`).String() == `[]`)
|
||||
assert(t, Get(`"hello"`, `@values`).String() == `["hello"]`)
|
||||
assert(t, Get(`[]`, `@values`).String() == `[]`)
|
||||
assert(t, Get(`[1,2,3]`, `@values`).String() == `[1,2,3]`)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue