mirror of
https://github.com/duke-git/lancet.git
synced 2026-02-04 12:52:28 +08:00
Slice: break (#200)
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.
This commit is contained in:
@@ -94,6 +94,7 @@ import (
|
||||
- [Join](#Join)
|
||||
- [Partition](#Partition)
|
||||
- [SetToDefaultIf](#SetToDefaultIf)
|
||||
- [Break](#Break)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
@@ -2600,4 +2601,37 @@ func main() {
|
||||
// [ b c d ]
|
||||
// 3
|
||||
}
|
||||
```
|
||||
|
||||
<span id="Break">Break</span>
|
||||
|
||||
<p>TBD</p>
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
func Break[T any](values []T, predicate func(T) bool) ([]T, []T)
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```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]
|
||||
}
|
||||
```
|
||||
@@ -94,6 +94,7 @@ import (
|
||||
- [Join](#Join)
|
||||
- [Partition](#Partition)
|
||||
- [SetToDefaultIf](#SetToDefaultIf)
|
||||
- [Break](#Break)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
@@ -2597,4 +2598,37 @@ func main() {
|
||||
// [ b c d ]
|
||||
// 3
|
||||
}
|
||||
```
|
||||
|
||||
<span id="Break">Break</span>
|
||||
|
||||
<p>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.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func Break[T any](values []T, predicate func(T) bool) ([]T, []T)
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```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]
|
||||
}
|
||||
```
|
||||
@@ -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) {
|
||||
|
||||
@@ -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]
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user