From a365a2b70002edfe9762ab33d74512f5f2ff1225 Mon Sep 17 00:00:00 2001 From: Kaarel Raspel Date: Thu, 11 Mar 2021 00:31:17 +0200 Subject: [PATCH 1/3] #50 Change `funk.Reduce` return type to `interface{}` --- builder.go | 2 +- chain_builder.go | 2 +- lazy_builder.go | 2 +- reduce.go | 5 ++--- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/builder.go b/builder.go index 0571fcc..6dfc814 100644 --- a/builder.go +++ b/builder.go @@ -39,7 +39,7 @@ type Builder interface { LastIndexOf(elem interface{}) int NotEmpty() bool Product() float64 - Reduce(reduceFunc, acc interface{}) float64 + Reduce(reduceFunc, acc interface{}) interface{} Sum() float64 Type() reflect.Type Value() interface{} diff --git a/chain_builder.go b/chain_builder.go index b03d76f..18226ab 100644 --- a/chain_builder.go +++ b/chain_builder.go @@ -125,7 +125,7 @@ func (b *chainBuilder) NotEmpty() bool { func (b *chainBuilder) Product() float64 { return Product(b.collection) } -func (b *chainBuilder) Reduce(reduceFunc, acc interface{}) float64 { +func (b *chainBuilder) Reduce(reduceFunc, acc interface{}) interface{} { return Reduce(b.collection, reduceFunc, acc) } func (b *chainBuilder) Sum() float64 { diff --git a/lazy_builder.go b/lazy_builder.go index 12e9b54..9ba1907 100644 --- a/lazy_builder.go +++ b/lazy_builder.go @@ -100,7 +100,7 @@ func (b *lazyBuilder) NotEmpty() bool { func (b *lazyBuilder) Product() float64 { return Product(b.exec()) } -func (b *lazyBuilder) Reduce(reduceFunc, acc interface{}) float64 { +func (b *lazyBuilder) Reduce(reduceFunc, acc interface{}) interface{} { return Reduce(b.exec(), reduceFunc, acc) } func (b *lazyBuilder) Sum() float64 { diff --git a/reduce.go b/reduce.go index de16a72..579b822 100644 --- a/reduce.go +++ b/reduce.go @@ -6,7 +6,7 @@ import ( // Reduce takes a collection and reduces it to a single value using a reduction // function (or a valid symbol) and an accumulator value. -func Reduce(arr, reduceFunc, acc interface{}) float64 { +func Reduce(arr, reduceFunc, acc interface{}) interface{} { arrValue := redirectValue(reflect.ValueOf(arr)) if !IsIteratee(arrValue.Interface()) { @@ -83,6 +83,5 @@ func Reduce(arr, reduceFunc, acc interface{}) float64 { accValue = result[0] } - resultInterface := accValue.Convert(returnType).Interface() - return resultInterface.(float64) + return accValue.Convert(returnType).Interface() } From 442500c5817df6c28eb20ee28ab76b779be7b782 Mon Sep 17 00:00:00 2001 From: Kaarel Raspel Date: Thu, 11 Mar 2021 00:31:43 +0200 Subject: [PATCH 2/3] #50 Fix tests --- chain_builder_test.go | 5 +++++ lazy_builder_test.go | 5 +++++ reduce_test.go | 14 ++++++++++---- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/chain_builder_test.go b/chain_builder_test.go index d7a1f77..0835b55 100644 --- a/chain_builder_test.go +++ b/chain_builder_test.go @@ -1012,6 +1012,11 @@ func TestChainReduce(t *testing.T) { ReduceFunc: '*', Acc: 1, }, + { + In: []string{"1", "2", "3", "4"}, + ReduceFunc: func(acc string, elem string) string { return acc + elem }, + Acc: "", + }, } for idx, tc := range testCases { diff --git a/lazy_builder_test.go b/lazy_builder_test.go index 6af577b..56816e7 100644 --- a/lazy_builder_test.go +++ b/lazy_builder_test.go @@ -1012,6 +1012,11 @@ func TestLazyReduce(t *testing.T) { ReduceFunc: '*', Acc: 1, }, + { + In: []string{"1", "2", "3", "4"}, + ReduceFunc: func(acc string, elem string) string { return acc + elem }, + Acc: "", + }, } for idx, tc := range testCases { diff --git a/reduce_test.go b/reduce_test.go index 60bdaa0..f976a2f 100644 --- a/reduce_test.go +++ b/reduce_test.go @@ -12,11 +12,11 @@ func TestReduce(t *testing.T) { Arr interface{} Func interface{} Acc interface{} - Result float64 + Result interface{} }{ { []int{1, 2, 3, 4}, - func(acc, elem int) int { return acc + elem }, + func(acc, elem float64) float64 { return acc + elem }, 0, float64(10), }, @@ -24,7 +24,7 @@ func TestReduce(t *testing.T) { &[]int16{1, 2, 3, 4}, '+', 5, - float64(15), + int16(15), }, { []float64{1.1, 2.2, 3.3}, @@ -36,7 +36,7 @@ func TestReduce(t *testing.T) { &[]int{1, 2, 3, 5}, func(acc int8, elem int16) int32 { return int32(acc) * int32(elem) }, 1, - float64(30), + int32(30), }, { []interface{}{1, 2, 3.3, 4}, @@ -44,6 +44,12 @@ func TestReduce(t *testing.T) { 1, float64(26.4), }, + { + []string{"1", "2", "3", "4"}, + func(acc string, elem string) string { return acc + elem }, + "", + "1234", + }, } for idx, test := range testCases { From cdeac5b616ce3eac2279d6ddc847db794dc2a1a4 Mon Sep 17 00:00:00 2001 From: Kaarel Raspel Date: Thu, 11 Mar 2021 00:31:50 +0200 Subject: [PATCH 3/3] #50 Update README --- README.rst | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 1e65ab6..92caebc 100644 --- a/README.rst +++ b/README.rst @@ -261,6 +261,26 @@ see also, typesafe implementations: FilterInt_, FilterInt64_, FilterFloat32_, Fi .. _FilterInt64: https://godoc.org/github.com/thoas/go-funk#FilterInt64 .. _FilterString: https://godoc.org/github.com/thoas/go-funk#FilterString +funk.Reduce +........... + +Reduces an iteratee based on an accumulator function or operation rune for numbers. + +.. code-block:: go + + // Using operation runes. '+' and '*' only supported. + r := funk.Reduce([]int{1, 2, 3, 4}, '+', float64(0)) // 10 + r := funk.Reduce([]int{1, 2, 3, 4}, '*', 1) // 24 + + // Using accumulator function + r := funk.Reduce([]int{1, 2, 3, 4}, func(acc float64, num int) float64 { + return acc + float64(num) + }, float64(0)) // 10 + + r := funk.Reduce([]int{1, 2, 3, 4}, func(acc string, num int) string { + return acc + fmt.Sprint(num) + }, "") // "1234" + funk.Find ......... @@ -318,7 +338,7 @@ Manipulates an iteratee (map, slice) and transforms it to another type: }) // map[string]string{"1": "Florent", "2": "Gilles"} funk.FlatMap -........ +............ Manipulates an iteratee (map, slice) and transforms it to to a flattened collection of another type: