Created
December 28, 2022 16:15
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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