diff --git a/docs/slice.md b/docs/slice.md index 9b04730..bec43ce 100644 --- a/docs/slice.md +++ b/docs/slice.md @@ -63,6 +63,7 @@ import ( - [Merge](#Merge) - [Reverse](#Reverse) - [Reduce](#Reduce) +- [ReduceBy](#ReduceBy) - [Replace](#Replace) - [ReplaceAll](#ReplaceAll) - [Repeat](#Repeat) @@ -1504,6 +1505,43 @@ func main() { } ``` + +### ReduceBy + +
Produces a value from slice by accumulating the result of each element as passed through the reducer function.
+ +Signature: + +```go +func ReduceBy[T any, U any](slice []T, initial U, reducer func(index int, item T, agg U) U) U +``` + +Example: + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result1 := slice.ReduceBy([]int{1, 2, 3, 4}, 0, func(_ int, item int, agg int) int { + return agg + item + }) + + result2 := slice.ReduceBy([]int{1, 2, 3, 4}, "", func(_ int, item int, agg string) string { + return agg + fmt.Sprintf("%v", item) + }) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 10 + // 1234 +} +``` + ### ReplaceReturns a copy of the slice with the first n non-overlapping instances of old replaced by new.
diff --git a/docs/slice_zh-CN.md b/docs/slice_zh-CN.md index f2a2fbe..ef92c16 100644 --- a/docs/slice_zh-CN.md +++ b/docs/slice_zh-CN.md @@ -63,6 +63,7 @@ import ( - [Merge](#Merge) - [Reverse](#Reverse) - [Reduce](#Reduce) +- [ReduceBy](#ReduceBy) - [Replace](#Replace) - [ReplaceAll](#ReplaceAll) - [Repeat](#Repeat) @@ -1505,6 +1506,44 @@ func main() { } ``` + +### ReduceBy + +对切片中执行reduce操作。
+ +函数签名: + +```go +func ReduceBy[T any, U any](slice []T, initial U, reducer func(index int, item T, agg U) U) U +``` + +示例: + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result1 := slice.ReduceBy([]int{1, 2, 3, 4}, 0, func(_ int, item int, agg int) int { + return agg + item + }) + + result2 := slice.ReduceBy([]int{1, 2, 3, 4}, "", func(_ int, item int, agg string) string { + return agg + fmt.Sprintf("%v", item) + }) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 10 + // 1234 +} +``` + + ### Replace返回切片的副本,其中前n个不重叠的old替换为new
diff --git a/slice/slice.go b/slice/slice.go index be6c74a..75f4396 100644 --- a/slice/slice.go +++ b/slice/slice.go @@ -492,6 +492,18 @@ func Reduce[T any](slice []T, iteratee func(index int, item1, item2 T) T, initia return result } +// ReduceBy produces a value from slice by accumulating the result of each element as passed through the reducer function. +// Play: todo +func ReduceBy[T any, U any](slice []T, initial U, reducer func(index int, item T, agg U) U) U { + accumulator := initial + + for i, v := range slice { + accumulator = reducer(i, v, accumulator) + } + + return accumulator +} + // Replace returns a copy of the slice with the first n non-overlapping instances of old replaced by new. // Play: https://go.dev/play/p/P5mZp7IhOFo func Replace[T comparable](slice []T, old T, new T, n int) []T { diff --git a/slice/slice_example_test.go b/slice/slice_example_test.go index 02fbd4b..74ad4c7 100644 --- a/slice/slice_example_test.go +++ b/slice/slice_example_test.go @@ -460,6 +460,23 @@ func ExampleReduce() { // 6 } +func ExampleReduceBy() { + result1 := ReduceBy([]int{1, 2, 3, 4}, 0, func(_ int, item int, agg int) int { + return agg + item + }) + + result2 := ReduceBy([]int{1, 2, 3, 4}, "", func(_ int, item int, agg string) string { + return agg + fmt.Sprintf("%v", item) + }) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 10 + // 1234 +} + func ExampleReplace() { strs := []string{"a", "b", "c", "a"} diff --git a/slice/slice_test.go b/slice/slice_test.go index 6b72966..e15c0ad 100644 --- a/slice/slice_test.go +++ b/slice/slice_test.go @@ -405,6 +405,22 @@ func TestReduce(t *testing.T) { } } +func TestReduceBy(t *testing.T) { + assert := internal.NewAssert(t, "TestReduce2") + + result1 := ReduceBy([]int{1, 2, 3, 4}, 0, func(_ int, item int, agg int) int { + return agg + item + }) + + result2 := ReduceBy([]int{1, 2, 3, 4}, "", func(_ int, item int, agg string) string { + return agg + fmt.Sprintf("%v", item) + }) + + assert.Equal(10, result1) + assert.Equal("1234", result2) + +} + func TestIntSlice(t *testing.T) { var nums []any nums = append(nums, 1, 2, 3)