Skip to content

Instantly share code, notes, and snippets.

@dcormier
Created December 28, 2022 16:15
Show Gist options
  • Save dcormier/03278a9726a121f6bbbdfb79cc4e3980 to your computer and use it in GitHub Desktop.
Save dcormier/03278a9726a121f6bbbdfb79cc4e3980 to your computer and use it in GitHub Desktop.
A generic golang function to reslice a slice into chunks not greater than a specified length.
package main
import (
"testing"
"github.com/stretchr/testify/require"
)
// Chunks re-slices a slice into chunks not longer than the specified max length.
// For example, a slice with seven elements being sliced into chunks of two will
// yield three slices of two, and a fourth slice will contain the remaining one.
//
// If an empty or nil slice is provided, nil is returned.
// If a max chunk length < 1 is provided, this will panic.
func Chunks[T any](values []T, maxChunkLen int) [][]T {
if maxChunkLen <= 0 {
panic("maxChunkLen must be > 0")
}
var chunks [][]T
for len(values) > 0 {
var chunk int
if remaining := len(values); remaining > maxChunkLen {
chunk = maxChunkLen
} else {
chunk = remaining
}
chunks = append(chunks, values[:chunk])
values = values[chunk:]
}
return chunks
}
func TestChunks(t *testing.T) {
testCases := []struct {
vals []int
maxChunkLen int
expect [][]int
}{
{
vals: nil,
maxChunkLen: 10,
expect: nil,
},
{
vals: []int{},
maxChunkLen: 10,
expect: nil,
},
{
vals: []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
maxChunkLen: 10,
expect: [][]int{
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
},
},
{
vals: []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
maxChunkLen: 11,
expect: [][]int{
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
},
},
{
vals: []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
maxChunkLen: 1,
expect: [][]int{
{0},
{1},
{2},
{3},
{4},
{5},
{6},
{7},
{8},
{9},
},
},
{
vals: []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
maxChunkLen: 2,
expect: [][]int{
{0, 1},
{2, 3},
{4, 5},
{6, 7},
{8, 9},
},
},
{
vals: []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
maxChunkLen: 3,
expect: [][]int{
{0, 1, 2},
{3, 4, 5},
{6, 7, 8},
{9},
},
},
}
for _, tC := range testCases {
t.Run("", func(t *testing.T) {
actual := Chunks(tC.vals, tC.maxChunkLen)
require.Equal(t, tC.expect, actual)
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment