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

Add slices reduce functions #67

Merged
merged 3 commits into from
Oct 8, 2024
Merged
Changes from 1 commit
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
Prev Previous commit
Next Next commit
slices: change ReduceWith to ReduceFrom and add comments
  • Loading branch information
Sypheos committed Oct 7, 2024
commit 599dc86f863efb2e303103e3cfc430f57db83b7f
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -33,6 +33,7 @@ require (
github.com/upfluence/log v0.0.5
github.com/upfluence/stats v0.1.4
github.com/upfluence/thrift v2.4.4+incompatible
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0
golang.org/x/oauth2 v0.19.0
golang.org/x/sync v0.8.0
golang.org/x/term v0.13.0
@@ -57,7 +58,6 @@ require (
go.uber.org/atomic v1.6.0 // indirect
go.uber.org/multierr v1.5.0 // indirect
golang.org/x/crypto v0.14.0 // indirect
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect
golang.org/x/sys v0.13.0 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
10 changes: 4 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
@@ -178,8 +178,8 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
@@ -560,8 +560,7 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ=
golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -618,9 +617,8 @@ golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgw
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE=
golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
15 changes: 10 additions & 5 deletions slices/reduce.go
Original file line number Diff line number Diff line change
@@ -2,18 +2,23 @@ package slices

import "golang.org/x/exp/constraints"

func ReduceWith[S ~[]E, E any, A any](s S, acc A, fn func(A, E) A) A {
for _, e := range s {
acc = fn(acc, e)
// ReduceFrom will iterate over each element of slice and call reduceFn for each.
// The return value of each reduceFn is passed to the next call of reduceFn as acc, or
// in other term at each iteration on the slice.
func ReduceFrom[S ~[]E, E any, A any](slice S, acc A, reduceFn func(acc A, elem E) A) A {
for _, e := range slice {
acc = reduceFn(acc, e)
}

return acc
}

func Reduce[S ~[]E, E any, A any](s S, fn func(A, E) A) A {
// Reduce does the same as ReduceFrom but use the zero value of A as
// the first value to be passed to reduceFn.
func Reduce[S ~[]E, E any, A any](slice S, reduceFn func(acc A, elem E) A) A {
var acc A

return ReduceWith(s, acc, fn)
return ReduceFrom(slice, acc, reduceFn)
}

type sumable interface {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will that not cause an issue? The fact that we have a private constraint on a publicly exposed func?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It won't bother the compiler since it is used as a constraint not as a value.

14 changes: 7 additions & 7 deletions slices/reduce_test.go
Original file line number Diff line number Diff line change
@@ -19,7 +19,7 @@ func TestReduceWith(t *testing.T) {
{slice: []int{1}, acc: 0, fn: func(a, b int) int { return a + b }, want: 1},
} {
t.Run("", func(t *testing.T) {
got := ReduceWith(tt.slice, tt.acc, tt.fn)
got := ReduceFrom(tt.slice, tt.acc, tt.fn)
assert.Equal(t, tt.want, got)
})
}
@@ -43,15 +43,15 @@ func TestReduce(t *testing.T) {

func TestSum(t *testing.T) {
t.Run("integer", func(t *testing.T) {
assert.Equal(t, Reduce([]int{1, 2}, Sum), 3)
assert.Equal(t, ReduceWith([]int{1, 2}, 22, Sum), 25)
assert.Equal(t, 3, Reduce([]int{1, 2}, Sum))
assert.Equal(t, 25, ReduceFrom([]int{1, 2}, 22, Sum))
})
t.Run("float", func(t *testing.T) {
assert.Equal(t, Reduce([]float64{1.1, 2.3}, Sum), 3.4)
assert.Equal(t, ReduceWith([]float64{1.1, 2.2}, 22.22, Sum), 25.52)
assert.Equal(t, 3.4, Reduce([]float64{1.1, 2.3}, Sum))
assert.Equal(t, 25.52, ReduceFrom([]float64{1.1, 2.2}, 22.22, Sum))
})
t.Run("string", func(t *testing.T) {
assert.Equal(t, Reduce([]string{"foo", "bar"}, Sum), "foobar")
assert.Equal(t, ReduceWith([]string{"foo", "bar"}, "buz", Sum), "buzfoobar")
assert.Equal(t, "foobar", Reduce([]string{"foo", "bar"}, Sum))
assert.Equal(t, "buzfoobar", ReduceFrom([]string{"foo", "bar"}, "buz", Sum))
})
}
Loading
Oops, something went wrong.