From a4e89bd7c111f5282966500bcece7fa366e6d592 Mon Sep 17 00:00:00 2001 From: dudaodong Date: Thu, 24 Oct 2024 15:38:12 +0800 Subject: [PATCH] feat: add ConcatBy --- docs/api/packages/slice.md | 48 +++++++++++++++++++++++++++++++++ docs/en/api/packages/slice.md | 51 +++++++++++++++++++++++++++++++++++ slice/slice.go | 19 +++++++++++++ slice/slice_example_test.go | 28 +++++++++++++++++++ slice/slice_test.go | 38 ++++++++++++++++++++++++++ 5 files changed, 184 insertions(+) diff --git a/docs/api/packages/slice.md b/docs/api/packages/slice.md index d30741a..4378029 100644 --- a/docs/api/packages/slice.md +++ b/docs/api/packages/slice.md @@ -107,6 +107,7 @@ import ( - [LeftPadding](#LeftPadding) - [Frequency](#Frequency) - [JoinFunc](#JoinFunc) +- [ConcatBy](#ConcatBy)
@@ -3016,4 +3017,51 @@ func main() { // Output: // A, B, C } +``` + +### ConcatBy + +

将切片中的元素连接成一个值,使用指定的分隔符和连接器函数。

+ +函数签名: + +```go +func ConcatBy[T any](slice []T, sep T, connector func(T, T) T) T +``` + +示例:[运行](todo) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + type Person struct { + Name string + Age int + } + + people := []Person{ + {Name: "Alice", Age: 30}, + {Name: "Bob", Age: 25}, + {Name: "Charlie", Age: 35}, + } + + sep := Person{Name: " | ", Age: 0} + + personConnector := func(a, b Person) Person { + return Person{Name: a.Name + b.Name, Age: a.Age + b.Age} + } + + result := slice.ConcatBy(people, sep, personConnector) + + fmt.Println(result.Name) + fmt.Println(result.Age) + + // Output: + // Alice | Bob | Charlie + // 90 +} ``` \ No newline at end of file diff --git a/docs/en/api/packages/slice.md b/docs/en/api/packages/slice.md index bf7c419..a3f80d2 100644 --- a/docs/en/api/packages/slice.md +++ b/docs/en/api/packages/slice.md @@ -106,6 +106,10 @@ import ( - [RightPadding](#RightPadding) - [LeftPadding](#LeftPadding) - [Frequency](#Frequency) +- [JoinFunc](#JoinFunc) +- [ConcatBy](#ConcatBy) + +
@@ -3009,4 +3013,51 @@ func main() { // Output: // A, B, C } +``` + +### ConcatBy + +

Concats the elements of a slice into a single value using the provided separator and connector function.

+ +Signature: + +```go +func ConcatBy[T any](slice []T, sep T, connector func(T, T) T) T +``` + +Example:[Run](todo) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + type Person struct { + Name string + Age int + } + + people := []Person{ + {Name: "Alice", Age: 30}, + {Name: "Bob", Age: 25}, + {Name: "Charlie", Age: 35}, + } + + sep := Person{Name: " | ", Age: 0} + + personConnector := func(a, b Person) Person { + return Person{Name: a.Name + b.Name, Age: a.Age + b.Age} + } + + result := slice.ConcatBy(people, sep, personConnector) + + fmt.Println(result.Name) + fmt.Println(result.Age) + + // Output: + // Alice | Bob | Charlie + // 90 +} ``` \ No newline at end of file diff --git a/slice/slice.go b/slice/slice.go index d4de36e..bb6bdbf 100644 --- a/slice/slice.go +++ b/slice/slice.go @@ -1411,3 +1411,22 @@ func JoinFunc[T any](slice []T, sep string, transform func(T) T) string { } return buf.String() } + +// ConcatBy concats the elements of a slice into a single value using the provided separator and connector function. +// Play: todo +func ConcatBy[T any](slice []T, sep T, connector func(T, T) T) T { + var result T + + if len(slice) == 0 { + return result + } + + for i, v := range slice { + result = connector(result, v) + if i < len(slice)-1 { + result = connector(result, sep) + } + } + + return result +} diff --git a/slice/slice_example_test.go b/slice/slice_example_test.go index 460283b..81ff39f 100644 --- a/slice/slice_example_test.go +++ b/slice/slice_example_test.go @@ -1272,3 +1272,31 @@ func ExampleJoinFunc() { // Output: // A, B, C } + +func ExampleConcatBy() { + type Person struct { + Name string + Age int + } + + people := []Person{ + {Name: "Alice", Age: 30}, + {Name: "Bob", Age: 25}, + {Name: "Charlie", Age: 35}, + } + + sep := Person{Name: " | ", Age: 0} + + personConnector := func(a, b Person) Person { + return Person{Name: a.Name + b.Name, Age: a.Age + b.Age} + } + + result := ConcatBy(people, sep, personConnector) + + fmt.Println(result.Name) + fmt.Println(result.Age) + + // Output: + // Alice | Bob | Charlie + // 90 +} diff --git a/slice/slice_test.go b/slice/slice_test.go index f05d472..9af7930 100644 --- a/slice/slice_test.go +++ b/slice/slice_test.go @@ -1856,3 +1856,41 @@ func TestJoinFunc(t *testing.T) { assert.Equal(expected, result) }) } + +func TestConcatBy(t *testing.T) { + t.Parallel() + + assert := internal.NewAssert(t, "TestConcatBy") + + t.Run("Join strings", func(t *testing.T) { + result := ConcatBy([]string{"Hello", "World"}, ", ", func(a, b string) string { + return a + b + }) + + expected := "Hello, World" + assert.Equal(expected, result) + }) + + t.Run("Join Person struct", func(t *testing.T) { + type Person struct { + Name string + Age int + } + + people := []Person{ + {Name: "Alice", Age: 30}, + {Name: "Bob", Age: 25}, + {Name: "Charlie", Age: 35}, + } + sep := Person{Name: " | ", Age: 0} + + personConnector := func(a, b Person) Person { + return Person{Name: a.Name + b.Name, Age: a.Age + b.Age} + } + + result := ConcatBy(people, sep, personConnector) + + assert.Equal("Alice | Bob | Charlie", result.Name) + assert.Equal(90, result.Age) + }) +}