diff --git a/slice.go b/slice.go index 170d830..4eec8e4 100644 --- a/slice.go +++ b/slice.go @@ -134,10 +134,12 @@ func Map[T any, R any, F MapFunc[T, R]](ss []T, funcInterface F) []R { return result } -type AccumulatorFunc[T any] func(acc T, i int, s T) T +type AccumulatorFunc[T any, R any] interface { + ~func(acc R, i int, s T) R +} // Reduce (aka inject) iterates over the slice of items and calls the accumulator function for each pass, storing the state in the acc variable through each pass. -func Reduce[T any](items []T, initialAccumulator T, f AccumulatorFunc[T]) T { +func Reduce[T any, R any, F AccumulatorFunc[T, R]](items []T, initialAccumulator R, f F) R { if items == nil { return initialAccumulator } diff --git a/slice_test.go b/slice_test.go index 0def020..0b335cc 100644 --- a/slice_test.go +++ b/slice_test.go @@ -56,6 +56,24 @@ func TestReduce(t *testing.T) { }) require.Equal(t, "55", result) + + type OddEven struct { + Odd int + Even int + } + + s2 := []int{0, 1, 2, 3, 4} + + result2 := slice.Reduce(s2, OddEven{}, func(acc OddEven, i int, s int) OddEven { + if s%2 == 0 { + acc.Even++ + } else { + acc.Odd++ + } + return acc + }) + + require.Equal(t, OddEven{Odd: 2, Even: 3}, result2) } func TestSelect(t *testing.T) {