From 462561b3efea668e0723977eca973b60275c3479 Mon Sep 17 00:00:00 2001 From: TonyDMorris Date: Fri, 23 Dec 2022 11:11:31 +0000 Subject: [PATCH] add chunkBy --- slices/slices.go | 17 +++++ slices/slices_test.go | 150 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 167 insertions(+) diff --git a/slices/slices.go b/slices/slices.go index cff0cd49e..4e52dbf9f 100644 --- a/slices/slices.go +++ b/slices/slices.go @@ -256,3 +256,20 @@ func Grow[S ~[]E, E any](s S, n int) S { func Clip[S ~[]E, E any](s S) S { return s[:len(s):len(s)] } + +// ChunkBy takes values from s and and appends them to chunks +// the appended values will have len <= n +// if n is 0 default chunk size will be 1 +// if len s == 0 base type [][]T is returned with len == 0 +func ChunkBy[T any](s []T, n int) (chunks [][]T) { + if n == 0 { + n = 1 + } + if len(s) == 0 { + return [][]T{} + } + for n < len(s) { + s, chunks = s[n:], append(chunks, s[0:n:n]) + } + return append(chunks, s) +} diff --git a/slices/slices_test.go b/slices/slices_test.go index 1d9ffd2f3..b1e1aeb32 100644 --- a/slices/slices_test.go +++ b/slices/slices_test.go @@ -6,6 +6,7 @@ package slices import ( "math" + "reflect" "strings" "testing" @@ -767,3 +768,152 @@ func BenchmarkReplace(b *testing.B) { } } + +func TestChunkBy(t *testing.T) { + + type args struct { + s []string + n int + } + tests := []struct { + name string + args args + wantChunks [][]string + }{ + { + name: "0 len slice 0 n", + args: args{ + s: []string{}, + n: 0, + }, + wantChunks: [][]string{}, + }, + { + name: "1 len slice 0 n", + args: args{ + s: []string{}, + n: 0, + }, + wantChunks: [][]string{}, + }, + { + name: "2 len slice 0 n", + args: args{ + s: []string{"", ""}, + n: 0, + }, + wantChunks: [][]string{{""}, {""}}, + }, + { + name: "3 len slice 0 n", + args: args{ + s: []string{"", "", ""}, + n: 0, + }, + wantChunks: [][]string{{""}, {""}, {""}}, + }, + { + name: "0 len slice 1 n", + args: args{ + s: []string{}, + n: 1, + }, + wantChunks: [][]string{}, + }, + { + name: "1 len slice 1 n", + args: args{ + s: []string{""}, + n: 1, + }, + wantChunks: [][]string{{""}}, + }, + { + name: "2 len slice 1 n", + args: args{ + s: []string{"", ""}, + n: 1, + }, + wantChunks: [][]string{{""}, {""}}, + }, + { + name: "3 len slice 1 n", + args: args{ + s: []string{"", "", ""}, + n: 1, + }, + wantChunks: [][]string{{""}, {""}, {""}}, + }, + { + name: "0 len slice 2 n", + args: args{ + s: []string{}, + n: 2, + }, + wantChunks: [][]string{}, + }, + { + name: "1 len slice 2 n", + args: args{ + s: []string{""}, + n: 2, + }, + wantChunks: [][]string{{""}}, + }, + { + name: "2 len slice 2 n", + args: args{ + s: []string{"", ""}, + n: 2, + }, + wantChunks: [][]string{{"", ""}}, + }, + { + name: "3 len slice 2 n", + args: args{ + s: []string{"", "", ""}, + n: 2, + }, + wantChunks: [][]string{{"", ""}, {""}}, + }, + { + name: "0 len slice 3 n", + args: args{ + s: []string{}, + n: 3, + }, + wantChunks: [][]string{}, + }, + { + name: "1 len slice 3 n", + args: args{ + s: []string{""}, + n: 3, + }, + wantChunks: [][]string{{""}}, + }, + { + name: "2 len slice 3 n", + args: args{ + s: []string{"", ""}, + n: 3, + }, + wantChunks: [][]string{{"", ""}}, + }, + { + name: "3 len slice 3 n", + args: args{ + s: []string{"", "", ""}, + n: 3, + }, + wantChunks: [][]string{{"", "", ""}}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if gotChunks := ChunkBy(tt.args.s, tt.args.n); !reflect.DeepEqual(gotChunks, tt.wantChunks) { + t.Errorf("ChunkBy() = %v, want %v", gotChunks, tt.wantChunks) + } + }) + } +}