go 33 lines · 6 steps

Splitting a slice into batches in Go

A generic Chunk helper divides any slice into fixed-size groups, and ProcessInBatches runs a callback over each one.

Explained by highlit
1package batch
2 
3import "fmt"
4 
5func Chunk[T any](items []T, size int) ([][]T, error) {
6 if size <= 0 {
7 return nil, fmt.Errorf("chunk size must be positive, got %d", size)
8 }
9 
10 chunks := make([][]T, 0, (len(items)+size-1)/size)
11 for start := 0; start < len(items); start += size {
12 end := start + size
13 if end > len(items) {
14 end = len(items)
15 }
16 chunks = append(chunks, items[start:end:end])
17 }
18 return chunks, nil
19}
20 
21func ProcessInBatches[T any](items []T, size int, fn func(batch []T) error) error {
22 chunks, err := Chunk(items, size)
23 if err != nil {
24 return err
25 }
26 
27 for i, batch := range chunks {
28 if err := fn(batch); err != nil {
29 return fmt.Errorf("batch %d/%d failed: %w", i+1, len(chunks), err)
30 }
31 }
32 return nil
33}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Type parameters let one function batch slices of any element type without duplication.
  2. 2Pre-sizing a slice with the ceiling division of length over size avoids repeated reallocation.
  3. 3Wrapping errors with %w preserves the original cause while adding batch context.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Splitting a slice into batches in Go — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code