forked from mirror/gjson
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"
|
||||
```
|
||||
|
||||
## 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
|
||||
|
||||
|
|
60
gjson.go
60
gjson.go
|
@ -152,6 +152,66 @@ func (t Result) Array() []Result {
|
|||
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.
|
||||
func (t Result) Map() map[string]Result {
|
||||
if t.Type != JSON {
|
||||
|
|
|
@ -163,6 +163,43 @@ func TestBasic(t *testing.T) {
|
|||
if mtok.String() != `["Brett","Elliotte"]` {
|
||||
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`)
|
||||
if mtok.String() != "1002.3" {
|
||||
t.Fatalf("expected %v, got %v", "1002.3", mtok.String())
|
||||
|
|
Loading…
Reference in New Issue