Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

slices: add ChunkBy #53

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions slices/slices.go
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,23 @@ 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)
}
// Rotation algorithm explanation:
//
// rotate left by 2
Expand Down Expand Up @@ -496,4 +513,5 @@ func Reverse[S ~[]E, E any](s S) {
for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
s[i], s[j] = s[j], s[i]
}

}
151 changes: 151 additions & 0 deletions slices/slices_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package slices

import (
"math"
"reflect"
"strings"
"testing"
)
Expand Down Expand Up @@ -998,6 +999,155 @@ 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)
}
})

}
func TestRotate(t *testing.T) {
const N = 10
s := make([]int, 0, N)
Expand Down Expand Up @@ -1050,5 +1200,6 @@ func TestReplaceGrowthRate(t *testing.T) {
want := int(math.Log(N) / math.Log(1.25)) // 1.25 == growth rate for large slices
if nGrow > want {
t.Errorf("too many grows. got:%d want:%d", nGrow, want)

}
}