mirror of https://github.com/tidwall/gjson.git
added ForEach function
This commit is contained in:
parent
86b1b630e4
commit
62892351c5
14
README.md
14
README.md
|
@ -185,6 +185,20 @@ name := gjson.Get(json, `programmers.#[lastName="Hunter"].firstName`)
|
||||||
println(name.String()) // prints "Elliotte"
|
println(name.String()) // prints "Elliotte"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Iterate through an object or array
|
||||||
|
|
||||||
|
The `ForEach` function allows for quickly iterating through an object or array.
|
||||||
|
The key and value are passed to the iterator function for objects.
|
||||||
|
Only the value is passed for arrays.
|
||||||
|
Returning `false` from an iterator will stop iteration.
|
||||||
|
|
||||||
|
```go
|
||||||
|
result := gjson.Get(json, "programmers")
|
||||||
|
result.ForEach(func(key, value Result) bool{
|
||||||
|
println(value.String())
|
||||||
|
return true // keep iterating
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
## Simple Parse and Get
|
## Simple Parse and Get
|
||||||
|
|
||||||
|
|
60
gjson.go
60
gjson.go
|
@ -152,6 +152,66 @@ func (t Result) Array() []Result {
|
||||||
return r.a
|
return r.a
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ForEach iterates through values.
|
||||||
|
// If the result represents a non-existent value, then no values will be iterated.
|
||||||
|
// If the result is an Object, the iterator will pass the key and value of each item.
|
||||||
|
// If the result is an Array, the iterator will only pass the value of each item.
|
||||||
|
// If the result is not a JSON array or object, the iterator will pass back one value equal to the result.
|
||||||
|
func (t Result) ForEach(iterator func(key, value Result) bool) {
|
||||||
|
if !t.Exists() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if t.Type != JSON {
|
||||||
|
iterator(Result{}, t)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
json := t.Raw
|
||||||
|
var keys bool
|
||||||
|
var i int
|
||||||
|
var key, value Result
|
||||||
|
for ; i < len(json); i++ {
|
||||||
|
if json[i] == '{' {
|
||||||
|
i++
|
||||||
|
key.Type = String
|
||||||
|
keys = true
|
||||||
|
break
|
||||||
|
} else if json[i] == '[' {
|
||||||
|
i++
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if json[i] > ' ' {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var str string
|
||||||
|
var vesc bool
|
||||||
|
var ok bool
|
||||||
|
for ; i < len(json); i++ {
|
||||||
|
if keys {
|
||||||
|
if json[i] != '"' {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
i, str, vesc, ok = parseString(json, i+1)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if vesc {
|
||||||
|
key.Str = unescape(str[1 : len(str)-1])
|
||||||
|
} else {
|
||||||
|
key.Str = str[1 : len(str)-1]
|
||||||
|
}
|
||||||
|
key.Raw = str
|
||||||
|
}
|
||||||
|
i, value, ok = parseAny(json, i, true)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !iterator(key, value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Map returns back an map of values. The result should be a JSON array.
|
// Map returns back an map of values. The result should be a JSON array.
|
||||||
func (t Result) Map() map[string]Result {
|
func (t Result) Map() map[string]Result {
|
||||||
if t.Type != JSON {
|
if t.Type != JSON {
|
||||||
|
|
|
@ -163,6 +163,43 @@ func TestBasic(t *testing.T) {
|
||||||
if mtok.String() != `["Brett","Elliotte"]` {
|
if mtok.String() != `["Brett","Elliotte"]` {
|
||||||
t.Fatalf("expected %v, got %v", `["Brett","Elliotte"]`, mtok.String())
|
t.Fatalf("expected %v, got %v", `["Brett","Elliotte"]`, mtok.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mtok = get(basicJSON, `loggy.programmers`)
|
||||||
|
var count int
|
||||||
|
mtok.ForEach(func(key, value Result) bool {
|
||||||
|
if key.Exists() {
|
||||||
|
t.Fatalf("expected %v, got %v", false, key.Exists())
|
||||||
|
}
|
||||||
|
count++
|
||||||
|
if count == 3 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if count == 1 {
|
||||||
|
i := 0
|
||||||
|
value.ForEach(func(key, value Result) bool {
|
||||||
|
switch i {
|
||||||
|
case 0:
|
||||||
|
if key.String() != "firstName" || value.String() != "Brett" {
|
||||||
|
t.Fatalf("expected %v/%v got %v/%v", "firstName", "Brett", key.String(), value.String())
|
||||||
|
}
|
||||||
|
case 1:
|
||||||
|
if key.String() != "lastName" || value.String() != "McLaughlin" {
|
||||||
|
t.Fatalf("expected %v/%v got %v/%v", "lastName", "McLaughlin", key.String(), value.String())
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
if key.String() != "email" || value.String() != "aaaa" {
|
||||||
|
t.Fatalf("expected %v/%v got %v/%v", "email", "aaaa", key.String(), value.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
if count != 3 {
|
||||||
|
t.Fatalf("expected %v, got %v", 3, count)
|
||||||
|
}
|
||||||
mtok = get(basicJSON, `loggy.programmers.#[age=101].firstName`)
|
mtok = get(basicJSON, `loggy.programmers.#[age=101].firstName`)
|
||||||
if mtok.String() != "1002.3" {
|
if mtok.String() != "1002.3" {
|
||||||
t.Fatalf("expected %v, got %v", "1002.3", mtok.String())
|
t.Fatalf("expected %v, got %v", "1002.3", mtok.String())
|
||||||
|
|
Loading…
Reference in New Issue