diff --git a/slice.go b/slice.go index bf69d3b0..b8610806 100644 --- a/slice.go +++ b/slice.go @@ -94,6 +94,16 @@ func ForEach[T any](collection []T, iteratee func(item T, index int)) { } } +// ForEachWhile iterates over elements of collection and invokes iteratee for each element +// collection return value decide to continue or break ,just like do while() +func ForEachWhile[T any](collection []T, iteratee func(item T, index int) (goon bool)) { + for i := range collection { + if !iteratee(collection[i], i) { + break + } + } +} + // Times invokes the iteratee n times, returning an array of the results of each invocation. // The iteratee is invoked with index as argument. // Play: https://go.dev/play/p/vgQj3Glr6lT diff --git a/slice_example_test.go b/slice_example_test.go index 1ee90ced..0d64d8f0 100644 --- a/slice_example_test.go +++ b/slice_example_test.go @@ -88,7 +88,21 @@ func ExampleForEach() { // 3 // 4 } +func ExampleForEachWhile() { + list := []int64{1, 2, -math.MaxInt, 4} + ForEachWhile(list, func(x int64, _ int) bool { + if x < 0 { + return false + } + fmt.Println(x) + return true + }) + + // Output: + // 1 + // 2 +} func ExampleTimes() { result := Times(3, func(i int) string { return strconv.FormatInt(int64(i), 10) diff --git a/slice_test.go b/slice_test.go index 0917e171..26ea7503 100644 --- a/slice_test.go +++ b/slice_test.go @@ -157,6 +157,29 @@ func TestForEach(t *testing.T) { is.IsIncreasing(callParams2) } +func TestForEachWhile(t *testing.T) { + t.Parallel() + is := assert.New(t) + + // check of callback is called for every element and in proper order + + var callParams1 []string + var callParams2 []int + + ForEachWhile([]string{"a", "b", "c"}, func(item string, i int) bool { + if item == "c" { + return false + } + callParams1 = append(callParams1, item) + callParams2 = append(callParams2, i) + return true + }) + + is.ElementsMatch([]string{"a", "b"}, callParams1) + is.ElementsMatch([]int{0, 1}, callParams2) + is.IsIncreasing(callParams2) +} + func TestUniq(t *testing.T) { t.Parallel() is := assert.New(t)