Skip to content

Commit 462561b

Browse files
committed
add chunkBy
1 parent 3c43f8b commit 462561b

File tree

2 files changed

+167
-0
lines changed

2 files changed

+167
-0
lines changed

slices/slices.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,3 +256,20 @@ func Grow[S ~[]E, E any](s S, n int) S {
256256
func Clip[S ~[]E, E any](s S) S {
257257
return s[:len(s):len(s)]
258258
}
259+
260+
// ChunkBy takes values from s and and appends them to chunks
261+
// the appended values will have len <= n
262+
// if n is 0 default chunk size will be 1
263+
// if len s == 0 base type [][]T is returned with len == 0
264+
func ChunkBy[T any](s []T, n int) (chunks [][]T) {
265+
if n == 0 {
266+
n = 1
267+
}
268+
if len(s) == 0 {
269+
return [][]T{}
270+
}
271+
for n < len(s) {
272+
s, chunks = s[n:], append(chunks, s[0:n:n])
273+
}
274+
return append(chunks, s)
275+
}

slices/slices_test.go

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package slices
66

77
import (
88
"math"
9+
"reflect"
910
"strings"
1011
"testing"
1112

@@ -767,3 +768,152 @@ func BenchmarkReplace(b *testing.B) {
767768
}
768769

769770
}
771+
772+
func TestChunkBy(t *testing.T) {
773+
774+
type args struct {
775+
s []string
776+
n int
777+
}
778+
tests := []struct {
779+
name string
780+
args args
781+
wantChunks [][]string
782+
}{
783+
{
784+
name: "0 len slice 0 n",
785+
args: args{
786+
s: []string{},
787+
n: 0,
788+
},
789+
wantChunks: [][]string{},
790+
},
791+
{
792+
name: "1 len slice 0 n",
793+
args: args{
794+
s: []string{},
795+
n: 0,
796+
},
797+
wantChunks: [][]string{},
798+
},
799+
{
800+
name: "2 len slice 0 n",
801+
args: args{
802+
s: []string{"", ""},
803+
n: 0,
804+
},
805+
wantChunks: [][]string{{""}, {""}},
806+
},
807+
{
808+
name: "3 len slice 0 n",
809+
args: args{
810+
s: []string{"", "", ""},
811+
n: 0,
812+
},
813+
wantChunks: [][]string{{""}, {""}, {""}},
814+
},
815+
{
816+
name: "0 len slice 1 n",
817+
args: args{
818+
s: []string{},
819+
n: 1,
820+
},
821+
wantChunks: [][]string{},
822+
},
823+
{
824+
name: "1 len slice 1 n",
825+
args: args{
826+
s: []string{""},
827+
n: 1,
828+
},
829+
wantChunks: [][]string{{""}},
830+
},
831+
{
832+
name: "2 len slice 1 n",
833+
args: args{
834+
s: []string{"", ""},
835+
n: 1,
836+
},
837+
wantChunks: [][]string{{""}, {""}},
838+
},
839+
{
840+
name: "3 len slice 1 n",
841+
args: args{
842+
s: []string{"", "", ""},
843+
n: 1,
844+
},
845+
wantChunks: [][]string{{""}, {""}, {""}},
846+
},
847+
{
848+
name: "0 len slice 2 n",
849+
args: args{
850+
s: []string{},
851+
n: 2,
852+
},
853+
wantChunks: [][]string{},
854+
},
855+
{
856+
name: "1 len slice 2 n",
857+
args: args{
858+
s: []string{""},
859+
n: 2,
860+
},
861+
wantChunks: [][]string{{""}},
862+
},
863+
{
864+
name: "2 len slice 2 n",
865+
args: args{
866+
s: []string{"", ""},
867+
n: 2,
868+
},
869+
wantChunks: [][]string{{"", ""}},
870+
},
871+
{
872+
name: "3 len slice 2 n",
873+
args: args{
874+
s: []string{"", "", ""},
875+
n: 2,
876+
},
877+
wantChunks: [][]string{{"", ""}, {""}},
878+
},
879+
{
880+
name: "0 len slice 3 n",
881+
args: args{
882+
s: []string{},
883+
n: 3,
884+
},
885+
wantChunks: [][]string{},
886+
},
887+
{
888+
name: "1 len slice 3 n",
889+
args: args{
890+
s: []string{""},
891+
n: 3,
892+
},
893+
wantChunks: [][]string{{""}},
894+
},
895+
{
896+
name: "2 len slice 3 n",
897+
args: args{
898+
s: []string{"", ""},
899+
n: 3,
900+
},
901+
wantChunks: [][]string{{"", ""}},
902+
},
903+
{
904+
name: "3 len slice 3 n",
905+
args: args{
906+
s: []string{"", "", ""},
907+
n: 3,
908+
},
909+
wantChunks: [][]string{{"", "", ""}},
910+
},
911+
}
912+
for _, tt := range tests {
913+
t.Run(tt.name, func(t *testing.T) {
914+
if gotChunks := ChunkBy(tt.args.s, tt.args.n); !reflect.DeepEqual(gotChunks, tt.wantChunks) {
915+
t.Errorf("ChunkBy() = %v, want %v", gotChunks, tt.wantChunks)
916+
}
917+
})
918+
}
919+
}

0 commit comments

Comments
 (0)