Skip to content

Instantly share code, notes, and snippets.

@VojtechVitek
Last active December 25, 2023 09:42
Show Gist options
  • Save VojtechVitek/00f8f22b0ab3ec221815fcd78f244edd to your computer and use it in GitHub Desktop.
Save VojtechVitek/00f8f22b0ab3ec221815fcd78f244edd to your computer and use it in GitHub Desktop.
Golang - Loop over slice in batches (run something in parallel on a sub-slice)
package main
import "fmt"
func main() {
slice := make([]int, 159)
// Split the slice into batches of 20 items.
batch := 20
for i := 0; i < len(slice); i += batch {
j := i + batch
if j > len(slice) {
j = len(slice)
}
fmt.Println(slice[i:j]) // Process the batch.
}
// Try it at https://play.golang.org/p/mgd814w8xx6
}
@robertotambunan
Copy link

robertotambunan commented Aug 28, 2018

for i := 0; i < len(recipients); i += batch {
		j := i + batch
		if j >= len(recipients) {
			j = len(recipients) - 1
		}
		fmt.Printf("recipients[%v:%v]\n", i, j)
}

I think you're expecting to iterate with this condition i < len(recipients)

@sangheee
Copy link

if j >= len(recipients) {
     j = len(recipients) 
}

When j is greater than or equal to len recipients), j is appropriate for len(recipients).
Because slice slicing does not include the slicing end point( recipients[i: j] are include i ~ j-1 in fact).

@VojtechVitek
Copy link
Author

Guys, the gist works correctly. I added a link to https://play.golang.org/p/mgd814w8xx6 so you can play around with it.

@gmonk
Copy link

gmonk commented Aug 12, 2020

Works like a charm .. This saved me so much time.. Thank you

@lezhnev74
Copy link

Here is a generic version:

func batchSlice[T any](in []T, size int) (out [][]T) {
	out = make([][]T, 0)

	if size == 0 {
		panic("slice batch size is 0")
	}

	for i := 0; i < len(in); i = i + size {
		j := i + size
		if j > len(in) {
			j = len(in)
		}
		out = append(out, in[i:j])
	}

	return
}

tests: https://go.dev/play/p/6szpCDNQsko

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment