diff --git a/hcloud/exp/kit/sliceutil/slice.go b/hcloud/exp/kit/sliceutil/slice.go index 3f035f6a..8866d47b 100644 --- a/hcloud/exp/kit/sliceutil/slice.go +++ b/hcloud/exp/kit/sliceutil/slice.go @@ -2,8 +2,11 @@ package sliceutil // Batches splits a slice into multiple batches of a desired size. func Batches[T any](all []T, size int) (batches [][]T) { + batches = make([][]T, 0, (len(all)/size)+1) for size < len(all) { - all, batches = all[size:], append(batches, all[:size]) + // Set the capacity of each chunk so that appending to a chunk does not + // modify the original slice. + all, batches = all[size:], append(batches, all[:size:size]) } return append(batches, all) } diff --git a/hcloud/exp/kit/sliceutil/slice_test.go b/hcloud/exp/kit/sliceutil/slice_test.go index 75e94f4a..54d591bb 100644 --- a/hcloud/exp/kit/sliceutil/slice_test.go +++ b/hcloud/exp/kit/sliceutil/slice_test.go @@ -11,7 +11,13 @@ func TestBatches(t *testing.T) { batches := Batches(all, 2) assert.Len(t, batches, 3) + assert.Equal(t, []int{1, 2}, batches[0]) + assert.Equal(t, 2, cap(batches[0])) + assert.Equal(t, []int{3, 4}, batches[1]) + assert.Equal(t, 2, cap(batches[1])) + assert.Equal(t, []int{5}, batches[2]) + assert.Equal(t, 1, cap(batches[2])) }