Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Slice: break #200

Merged
merged 1 commit into from
Mar 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions docs/api/packages/slice.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ import (
- [Join](#Join)
- [Partition](#Partition)
- [SetToDefaultIf](#SetToDefaultIf)
- [Break](#Break)

<div STYLE="page-break-after: always;"></div>

Expand Down Expand Up @@ -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]
}
```
34 changes: 34 additions & 0 deletions docs/en/api/packages/slice.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ import (
- [Join](#Join)
- [Partition](#Partition)
- [SetToDefaultIf](#SetToDefaultIf)
- [Break](#Break)

<div STYLE="page-break-after: always;"></div>

Expand Down Expand Up @@ -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]
}
```
24 changes: 24 additions & 0 deletions slice/slice.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
13 changes: 13 additions & 0 deletions slice/slice_example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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]
}
39 changes: 39 additions & 0 deletions slice/slice_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Loading