From 541e6d4ea32815f6d59dd9b6b4154cbdeb5aebfa Mon Sep 17 00:00:00 2001 From: dudaodong Date: Mon, 4 Sep 2023 11:30:50 +0800 Subject: [PATCH] feat: add Partition for slice --- slice/slice.go | 34 ++++++++++++++++++++++++++++++++-- slice/slice_example_test.go | 17 +++++++++++++++++ slice/slice_test.go | 10 ++++++++++ 3 files changed, 59 insertions(+), 2 deletions(-) diff --git a/slice/slice.go b/slice/slice.go index 6a1dc47..5f412dc 100644 --- a/slice/slice.go +++ b/slice/slice.go @@ -1192,10 +1192,40 @@ func KeyBy[T any, U comparable](slice []T, iteratee func(item T) U) map[U]T { // Join the slice item with specify separator. // Play: https://go.dev/play/p/huKzqwNDD7V -func Join[T any](s []T, separator string) string { - str := Map(s, func(_ int, item T) string { +func Join[T any](slice []T, separator string) string { + str := Map(slice, func(_ int, item T) string { return fmt.Sprint(item) }) return strings.Join(str, separator) } + +// Partition all slice elements with the evaluation of the given predicate functions. +// todo +func Partition[T any](slice []T, predicates ...func(item T) bool) [][]T { + l := len(predicates) + + result := make([][]T, l+1) + + for _, item := range slice { + processed := false + + for i, f := range predicates { + if f == nil { + panic("predicate function must not be nill") + } + + if f(item) { + result[i] = append(result[i], item) + processed = true + break + } + } + + if !processed { + result[l] = append(result[l], item) + } + } + + return result +} diff --git a/slice/slice_example_test.go b/slice/slice_example_test.go index c2a3e60..a5e7049 100644 --- a/slice/slice_example_test.go +++ b/slice/slice_example_test.go @@ -1046,3 +1046,20 @@ func ExampleJoin() { // 1,2,3,4,5 // 1-2-3-4-5 } + +func ExamplePartition() { + nums := []int{1, 2, 3, 4, 5} + + result1 := Partition(nums) + result2 := Partition(nums, func(n int) bool { return n%2 == 0 }) + result3 := Partition(nums, func(n int) bool { return n == 1 || n == 2 }, func(n int) bool { return n == 2 || n == 3 || n == 4 }) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // [[1 2 3 4 5]] + // [[2 4] [1 3 5]] + // [[1 2] [3 4] [5]] +} diff --git a/slice/slice_test.go b/slice/slice_test.go index fee8c23..2284674 100644 --- a/slice/slice_test.go +++ b/slice/slice_test.go @@ -1175,3 +1175,13 @@ func TestJoin(t *testing.T) { assert.Equal("1,2,3,4,5", result1) assert.Equal("1-2-3-4-5", result2) } + +func TestPartition(t *testing.T) { + t.Parallel() + + assert := internal.NewAssert(t, "TestPartition") + + assert.Equal([][]int{{1, 2, 3, 4, 5}}, Partition([]int{1, 2, 3, 4, 5})) + assert.Equal([][]int{{2, 4}, {1, 3, 5}}, Partition([]int{1, 2, 3, 4, 5}, func(n int) bool { return n%2 == 0 })) + assert.Equal([][]int{{1, 2}, {3, 4}, {5}}, Partition([]int{1, 2, 3, 4, 5}, func(n int) bool { return n == 1 || n == 2 }, func(n int) bool { return n == 2 || n == 3 || n == 4 })) +}