From c01c9d14b4a62b6c7d299ca421a1b7982259641c Mon Sep 17 00:00:00 2001 From: dudaodong Date: Tue, 4 Apr 2023 17:54:54 +0800 Subject: [PATCH] feat: add ReduceRight --- docs/slice.md | 32 +++++++++++++++++++++++++++++++- docs/slice_zh-CN.md | 31 ++++++++++++++++++++++++++++++- slice/slice.go | 12 ++++++++++++ slice/slice_example_test.go | 11 +++++++++++ slice/slice_test.go | 12 +++++++++++- 5 files changed, 95 insertions(+), 3 deletions(-) diff --git a/docs/slice.md b/docs/slice.md index bec43ce..b3e0f3c 100644 --- a/docs/slice.md +++ b/docs/slice.md @@ -64,6 +64,7 @@ import ( - [Reverse](#Reverse) - [Reduce](#Reduce) - [ReduceBy](#ReduceBy) +- [ReduceRight](#ReduceRight) - [Replace](#Replace) - [ReplaceAll](#ReplaceAll) - [Repeat](#Repeat) @@ -1505,7 +1506,6 @@ func main() { } ``` - ### ReduceBy

Produces a value from slice by accumulating the result of each element as passed through the reducer function.

@@ -1542,6 +1542,36 @@ func main() { } ``` +### ReduceRight + +

ReduceRight is like ReduceBy, but it iterates over elements of slice from right to left.

+ +Signature: + +```go +func ReduceRight[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() { + result := slice.ReduceRight([]int{1, 2, 3, 4}, "", func(_ int, item int, agg string) string { + return agg + fmt.Sprintf("%v", item) + }) + + fmt.Println(result) + + // Output: + // 4321 +} +``` + ### Replace

Returns 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 ef92c16..0d98644 100644 --- a/docs/slice_zh-CN.md +++ b/docs/slice_zh-CN.md @@ -64,6 +64,7 @@ import ( - [Reverse](#Reverse) - [Reduce](#Reduce) - [ReduceBy](#ReduceBy) +- [ReduceRight](#ReduceRight) - [Replace](#Replace) - [ReplaceAll](#ReplaceAll) - [Repeat](#Repeat) @@ -1506,7 +1507,6 @@ func main() { } ``` - ### ReduceBy

对切片中执行reduce操作。

@@ -1543,6 +1543,35 @@ func main() { } ``` +### ReduceRight + +

类似ReduceBy操作,迭代切片元素顺序从右至左。

+ +函数签名: + +```go +func ReduceRight[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() { + result := slice.ReduceRight([]int{1, 2, 3, 4}, "", func(_ int, item int, agg string) string { + return agg + fmt.Sprintf("%v", item) + }) + + fmt.Println(result) + + // Output: + // 4321 +} +``` ### Replace diff --git a/slice/slice.go b/slice/slice.go index 75f4396..39ea647 100644 --- a/slice/slice.go +++ b/slice/slice.go @@ -504,6 +504,18 @@ func ReduceBy[T any, U any](slice []T, initial U, reducer func(index int, item T return accumulator } +// ReduceRight is like ReduceBy, but it iterates over elements of slice from right to left. +// Play: todo +func ReduceRight[T any, U any](slice []T, initial U, reducer func(index int, item T, agg U) U) U { + accumulator := initial + + for i := len(slice) - 1; i >= 0; i-- { + accumulator = reducer(i, slice[i], 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 74ad4c7..d8d3a67 100644 --- a/slice/slice_example_test.go +++ b/slice/slice_example_test.go @@ -477,6 +477,17 @@ func ExampleReduceBy() { // 1234 } +func ExampleReduceRight() { + result := ReduceRight([]int{1, 2, 3, 4}, "", func(_ int, item int, agg string) string { + return agg + fmt.Sprintf("%v", item) + }) + + fmt.Println(result) + + // Output: + // 4321 +} + func ExampleReplace() { strs := []string{"a", "b", "c", "a"} diff --git a/slice/slice_test.go b/slice/slice_test.go index e15c0ad..805403b 100644 --- a/slice/slice_test.go +++ b/slice/slice_test.go @@ -406,7 +406,7 @@ func TestReduce(t *testing.T) { } func TestReduceBy(t *testing.T) { - assert := internal.NewAssert(t, "TestReduce2") + assert := internal.NewAssert(t, "TestReduceBy") result1 := ReduceBy([]int{1, 2, 3, 4}, 0, func(_ int, item int, agg int) int { return agg + item @@ -421,6 +421,16 @@ func TestReduceBy(t *testing.T) { } +func TestReduceRight(t *testing.T) { + assert := internal.NewAssert(t, "ReduceRight") + + result := ReduceRight([]int{1, 2, 3, 4}, "", func(_ int, item int, agg string) string { + return agg + fmt.Sprintf("%v", item) + }) + + assert.Equal("4321", result) +} + func TestIntSlice(t *testing.T) { var nums []any nums = append(nums, 1, 2, 3)