diff --git a/docs/api/packages/slice.md b/docs/api/packages/slice.md index ef05877..cf1cab4 100644 --- a/docs/api/packages/slice.md +++ b/docs/api/packages/slice.md @@ -94,6 +94,7 @@ import ( - [Join](#Join) - [Partition](#Partition) - [SetToDefaultIf](#SetToDefaultIf) +- [Break](#Break)
@@ -2600,4 +2601,37 @@ func main() { // [ b c d ] // 3 } +``` + +Break + +

TBD

+ +示例: + +```go +func Break[T any](values []T, predicate func(T) bool) ([]T, []T) +``` + +Example: + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5} + even := func(n int) bool { return n%2 == 0 } + + resultEven, resultAfterFirstEven := Break(nums, even) + + fmt.Println(resultEven) + fmt.Println(resultAfterFirstEven) + + // Output: + // [1] + // [2 3 4 5] +} ``` \ No newline at end of file diff --git a/docs/en/api/packages/slice.md b/docs/en/api/packages/slice.md index 0607a6c..60e3e90 100644 --- a/docs/en/api/packages/slice.md +++ b/docs/en/api/packages/slice.md @@ -94,6 +94,7 @@ import ( - [Join](#Join) - [Partition](#Partition) - [SetToDefaultIf](#SetToDefaultIf) +- [Break](#Break)
@@ -2597,4 +2598,37 @@ func main() { // [ b c d ] // 3 } +``` + +Break + +

Splits a slice into two based on a predicate function. It starts appending to the second slice after the first element that matches the predicate. All elements after the first match are included in the second slice, regardless of whether they match the predicate or not.

+ +Signature: + +```go +func Break[T any](values []T, predicate func(T) bool) ([]T, []T) +``` + +Example: + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + nums := []int{1, 2, 3, 4, 5} + even := func(n int) bool { return n%2 == 0 } + + resultEven, resultAfterFirstEven := Break(nums, even) + + fmt.Println(resultEven) + fmt.Println(resultAfterFirstEven) + + // Output: + // [1] + // [2 3 4 5] +} ``` \ No newline at end of file diff --git a/slice/slice.go b/slice/slice.go index c858ede..bf0b2b5 100644 --- a/slice/slice.go +++ b/slice/slice.go @@ -1239,6 +1239,30 @@ func Partition[T any](slice []T, predicates ...func(item T) bool) [][]T { return result } +// Breaks a list into two parts at the point where the predicate for the first time is true. +// Play: Todo +func Break[T any](values []T, predicate func(T) bool) ([]T, []T) { + a := make([]T, 0) + b := make([]T, 0) + if len(values) == 0 { + return a, b + } + matched := false + for _, value := range values { + + if !matched && predicate(value) { + matched = true + } + + if matched { + b = append(b, value) + } else { + a = append(a, value) + } + } + return a, b +} + // Random get a random item of slice, return idx=-1 when slice is empty // Play: https://go.dev/play/p/UzpGQptWppw func Random[T any](slice []T) (val T, idx int) { diff --git a/slice/slice_example_test.go b/slice/slice_example_test.go index 037ea64..39361a2 100644 --- a/slice/slice_example_test.go +++ b/slice/slice_example_test.go @@ -1112,3 +1112,16 @@ func ExampleSetToDefaultIf() { // [ b c d ] // 3 } + +func ExampleBreak() { + nums := []int{1, 2, 3, 4, 5} + even := func(n int) bool { return n%2 == 0 } + + resultEven, resultAfterFirstEven := Break(nums, even) + fmt.Println(resultEven) + fmt.Println(resultAfterFirstEven) + + // Output: + // [1] + // [2 3 4 5] +} diff --git a/slice/slice_test.go b/slice/slice_test.go index 582a156..aa413f3 100644 --- a/slice/slice_test.go +++ b/slice/slice_test.go @@ -1357,3 +1357,42 @@ func TestSetToDefaultIf(t *testing.T) { assert.Equal(2, count) }) } + +func TestBreak(t *testing.T) { + t.Parallel() + + assert := internal.NewAssert(t, "TestBreak") + + // Test with integers + nums := []int{1, 2, 3, 4, 5} + even := func(n int) bool { return n%2 == 0 } + + resultEven, resultAfterFirstEven := Break(nums, even) + assert.Equal([]int{1}, resultEven) + assert.Equal([]int{2, 3, 4, 5}, resultAfterFirstEven) + + // Test with strings + strings := []string{"apple", "banana", "cherry", "date", "elderberry"} + startsWithA := func(s string) bool { return s[0] == 'a' } + + resultStartsWithA, resultAfterFirstStartsWithA := Break(strings, startsWithA) + assert.Equal([]string{}, resultStartsWithA) + assert.Equal([]string{"apple", "banana", "cherry", "date", "elderberry"}, resultAfterFirstStartsWithA) + + // Test with empty slice + emptySlice := []int{} + resultEmpty, _ := Break(emptySlice, even) + assert.Equal([]int{}, resultEmpty) + + // Test with all elements satisfying the predicate + allEven := []int{2, 4, 6, 8, 10} + emptyResult, resultAllEven := Break(allEven, even) + assert.Equal([]int{2, 4, 6, 8, 10}, resultAllEven) + assert.Equal([]int{}, emptyResult) + + // Test with no elements satisfying the predicate + allOdd := []int{1, 3, 5, 7, 9} + resultAllOdd, emptyResult := Break(allOdd, even) + assert.Equal([]int{1, 3, 5, 7, 9}, resultAllOdd) + assert.Equal([]int{}, emptyResult) +}