Skip to content

Iteration Methods

Processor provides multiple methods for iterating over JSON arrays and objects.

Foreach

Signature: func (p *Processor) Foreach(jsonStr string, fn func(key any, item *IterableValue), cfg ...Config)

Iterates over a JSON array or object.

go
p.Foreach(data, func(key any, item *json.IterableValue) {
    fmt.Printf("Key: %v, Value: %v\n", key, item.GetData())
})

When iterating an array: key is the index (int) When iterating an object: key is the key name (string)

ForeachWithPath

Signature: func (p *Processor) ForeachWithPath(jsonStr, path string, fn func(key any, item *IterableValue), cfg ...Config) error

Iterates by path, returns an error.

go
err := p.ForeachWithPath(data, "items", func(key any, item *json.IterableValue) {
    fmt.Printf("[%v] %v\n", key, item.GetData())
})

Useful for:

  • Iterating nested arrays
  • Iterating objects at a specified path

ForeachNested

Signature: func (p *Processor) ForeachNested(jsonStr string, fn func(key any, item *IterableValue), cfg ...Config)

Recursively iterates through all nested levels.

go
p.ForeachNested(data, func(key any, item *json.IterableValue) {
    fmt.Printf("Key: %v, Value: %v\n", key, item.GetData())
})

Example data:

json
{
  "user": {
    "name": "test",
    "profile": {
      "age": 25,
      "tags": ["a", "b"]
    }
  }
}

Output:

text
Key: user, Value: map[string]any{...}
Key: name, Value: test
Key: profile, Value: map[string]any{...}
Key: age, Value: 25
Key: tags, Value: []any{...}
...

ForeachReturn

Signature: func (p *Processor) ForeachReturn(jsonStr string, fn func(key any, item *IterableValue), cfg ...Config) (string, error)

Iterates the JSON data and returns the re-serialized JSON string. The callback is read-only.

go
result, err := p.ForeachReturn(data, func(key any, item *json.IterableValue) {
    // Read-only processing
})

Useful for scenarios where you need to continue chained operations after iteration.

ForeachWithError

Signature: func (p *Processor) ForeachWithError(jsonStr, path string, fn func(key any, item *IterableValue) error, cfg ...Config) error

Iterates by path, callback supports returning errors.

go
err := p.ForeachWithError(data, "items", func(key any, item *json.IterableValue) error {
    if item.GetInt("id") == 0 {
        return fmt.Errorf("invalid item at index %v", key)
    }
    return nil // Continue iteration
})

ForeachNestedWithError

Signature: func (p *Processor) ForeachNestedWithError(jsonStr string, fn func(key any, item *IterableValue) error, cfg ...Config) error

Recursively iterates through all nested levels, callback supports returning errors.

go
err := p.ForeachNestedWithError(data, func(key any, item *json.IterableValue) error {
    fmt.Printf("Key: %v, Value: %v\n", key, item.GetData())
    return nil
})

ForeachWithPathAndIterator

Signature: func (p *Processor) ForeachWithPathAndIterator(jsonStr, path string, fn func(key any, item *IterableValue, currentPath string) IteratorControl, cfg ...Config) error

Iterates by path and provides current path information. Use IteratorControl to control the iteration flow.

go
err := p.ForeachWithPathAndIterator(data, "items", func(key any, item *json.IterableValue, currentPath string) json.IteratorControl {
    fmt.Printf("Path: %s, Key: %v\n", currentPath, key)
    if item.GetInt("id") == targetID {
        return json.IteratorBreak // Stop iteration
    }
    return json.IteratorNormal // Continue iteration
})

ForeachWithPathAndControl

Signature: func (p *Processor) ForeachWithPathAndControl(jsonStr, path string, fn func(key any, value any) IteratorControl, cfg ...Config) error

Iterates raw values by path, using IteratorControl for flow control.

go
err := p.ForeachWithPathAndControl(data, "items", func(key any, value any) json.IteratorControl {
    fmt.Printf("Key: %v, Value: %v\n", key, value)
    return json.IteratorNormal
})

IterableValue

The IterableValue in iteration callbacks provides the following capabilities:

MethodDescription
GetData() anyGet current value
Get(path string) anyGet value by path
GetString(key string) stringGet string value
GetInt(key string) intGet integer value
GetFloat64(key string) float64Get float64 value
GetBool(key string) boolGet boolean value
GetArray(key string) []anyGet array value
GetObject(key string) map[string]anyGet object value
GetWithDefault(key string, defaultValue any) anyGet value (with default)
GetStringWithDefault(key string, defaultValue string) stringGet string (with default)
GetIntWithDefault(key string, defaultValue int) intGet integer (with default)
GetFloat64WithDefault(key string, defaultValue float64) float64Get float64 (with default)
GetBoolWithDefault(key string, defaultValue bool) boolGet boolean (with default)
Exists(key string) boolCheck if field exists
IsNull(key string) boolCheck if field is null
IsNullData() boolCheck if current value is null
IsEmpty(key string) boolCheck if field is empty
IsEmptyData() boolCheck if current value is empty
Break() errorReturn break signal to stop iteration
Release()Release resources back to object pool
ForeachNested(path string, fn func(key any, item *IterableValue))Recursively iterate nested structures

Method Comparison

MethodPath ParameterRecursiveReturn ValueError Callback
ForeachNoNoNoneNo
ForeachWithPathYesNoerrorNo
ForeachNestedNoYesNoneNo
ForeachReturnNoNo(string, error)No
ForeachWithErrorYesNoerrorYes
ForeachNestedWithErrorNoYeserrorYes
ForeachWithPathAndIteratorYesNoerrorIteratorControl
ForeachWithPathAndControlYesNoerrorIteratorControl

File Iteration Methods

Processor provides methods for iterating directly from files, suitable for processing large JSON files.

ForeachFile

Signature: func (p *Processor) ForeachFile(filePath string, fn func(key any, item *IterableValue) error, cfg ...Config) error

Loads JSON from a file and iterates over it.

Parameters

NameTypeDescription
filePathstringJSON file path
fnfunc(key any, item *IterableValue) errorIteration callback
go
err := p.ForeachFile("data.json", func(key any, item *json.IterableValue) error {
    fmt.Printf("[%v] %v\n", key, item.GetData())
    return nil // Continue iteration
})

ForeachFileWithPath

Signature: func (p *Processor) ForeachFileWithPath(filePath, path string, fn func(key any, item *IterableValue) error, cfg ...Config) error

Loads JSON from a file and iterates by path.

go
// Only iterate the users array
err := p.ForeachFileWithPath("data.json", ".users", func(key any, item *json.IterableValue) error {
    name := item.GetString("name")
    fmt.Printf("User: %s\n", name)
    return nil
})

ForeachFileChunked

Signature: func (p *Processor) ForeachFileChunked(filePath string, chunkSize int, fn func(chunk []*IterableValue) error, cfg ...Config) (err error)

Iterates a JSON array from a file in chunks, suitable for batch processing large datasets.

Parameters

NameTypeDescription
filePathstringJSON file path
chunkSizeintNumber of items per batch (defaults to 100 when <=0)
fnfunc(chunk []*IterableValue) errorBatch processing callback
go
// Process 100 records per batch
err := p.ForeachFileChunked("large_data.json", 100, func(chunk []*json.IterableValue) error {
    // Batch insert into database
    records := make([]Record, len(chunk))
    for i, item := range chunk {
        records[i] = Record{
            ID:   item.GetInt("id"),
            Name: item.GetString("name"),
        }
    }
    return db.BatchInsert(records)
})

Use Cases

  • Batch database insertion
  • Batched API calls
  • Memory-constrained large file processing

ForeachFileNested

Signature: func (p *Processor) ForeachFileNested(filePath string, fn func(key any, item *IterableValue) error, cfg ...Config) error

Loads JSON from a file and recursively iterates through all nested structures.

go
err := p.ForeachFileNested("config.json", func(key any, item *json.IterableValue) error {
    // Traverse all key-value pairs at all levels
    fmt.Printf("Path: %v, Type: %T\n", key, item.GetData())
    return nil
})

Example Data:

json
{
  "database": {
    "host": "localhost",
    "port": 5432,
    "pool": {
      "min": 5,
      "max": 20
    }
  }
}

Output:

text
Path: database, Type: map[string]any
Path: host, Type: string
Path: port, Type: float64
Path: pool, Type: map[string]any
Path: min, Type: float64
Path: max, Type: float64

File Iteration Method Comparison

MethodPath ParameterRecursiveChunkedSuitable For
ForeachFileNoNoNoSimple file traversal
ForeachFileWithPathYesNoNoTargeted traversal
ForeachFileChunkedNoNoYesBatch processing, memory-constrained
ForeachFileNestedNoYesNoDeep traversal of all nodes

Iteration Control

Breaking Iteration

Returning item.Break() in the callback function breaks the iteration:

go
err := p.ForeachFile("data.json", func(key any, item *json.IterableValue) error {
    if item.GetInt("id") == targetID {
        // Found target, stop iteration
        return item.Break()
    }
    return nil // Continue iteration
})

Error Handling

Returning other errors breaks the iteration and returns that error:

go
err := p.ForeachFile("data.json", func(key any, item *json.IterableValue) error {
    if item.GetString("status") == "error" {
        return fmt.Errorf("found error record: %v", key)
    }
    return nil
})
if err != nil {
    log.Printf("Iteration interrupted: %v", err)
}