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

feat(slice): add ForAll & Exists funcs #561

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
30 changes: 29 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ Supported helpers for slices:
- [IsSorted](#issorted)
- [IsSortedByKey](#issortedbykey)
- [Splice](#Splice)
- [ForAll](#ForAll)
- [Exists](#Exists)

Supported helpers for maps:

Expand Down Expand Up @@ -1041,6 +1043,32 @@ result = lo.Splice([]string{"a", "b"}, 42, "1", "2")

[[play](https://go.dev/play/p/G5_GhkeSUBA)]

### ForAll

ForAll returns true if all a slice items satisfy the predicate.

```go
result := ForAll([]int{2, 4, 6, 8}, func(x int) bool {
return x%2 == 0
})
// true
```

[[play](https://go.dev/play/p/K9Jt5gZ0HW4)]

### Exists

Exists returns true if at least one element satisfies the predicate.

```go
result := Exists([]int{2, 4, 6, 8, 9}, func(x int) bool {
return x == 8
})
// true
```

[[play](https://go.dev/play/p/2lCKJ_hFUWV)]

### Keys

Creates a slice of the map keys.
Expand All @@ -1062,7 +1090,7 @@ keys := lo.Keys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"bar": 3})

### UniqKeys

Creates an array of unique map keys.
Creates an array of unique map keys.

```go
keys := lo.UniqKeys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"baz": 3})
Expand Down
24 changes: 24 additions & 0 deletions slice.go
Original file line number Diff line number Diff line change
Expand Up @@ -693,3 +693,27 @@ func Splice[T any, Slice ~[]T](collection Slice, i int, elements ...T) Slice {

return append(append(append(output, collection[:i]...), elements...), collection[i:]...)
}

// ForAll returns true if all a slice items satisfy the predicate.
// Play: https://go.dev/play/p/K9Jt5gZ0HW4
func ForAll[T any, Slice ~[]T](collection Slice, predicate func(item T) bool) bool {
for i := range collection {
if !predicate(collection[i]) {
return false
}
}

return true
}

// Exists returns true if at least one element satisfies the predicate.
// Play: https://go.dev/play/p/2lCKJ_hFUWV
func Exists[T any, Slice ~[]T](collection Slice, predicate func(item T) bool) bool {
for i := range collection {
if predicate(collection[i]) {
return true
}
}

return false
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these not direct copies of EveryBy() and SomeBy()?

35 changes: 35 additions & 0 deletions slice_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1029,3 +1029,38 @@ func TestSplice(t *testing.T) {
nonempty := Splice(allStrings, 1, "1", "2")
is.IsType(nonempty, allStrings, "type preserved")
}

func TestForAll(t *testing.T) {
t.Parallel()
is := assert.New(t)

r1 := ForAll([]int{2, 4, 6, 8}, func(x int) bool {
return x%2 == 0
})
is.True(r1)

r2 := ForAll([]int{}, func(x int) bool {
return x%2 == 0
})
is.True(r2)

r3 := ForAll([]int{2, 4, 6, 8, 9}, func(x int) bool {
return x%2 == 0
})
is.False(r3)
}

func TestExists(t *testing.T) {
t.Parallel()
is := assert.New(t)

r1 := Exists([]string{"one", "two", "three"}, func(x string) bool {
return x == "two"
})
is.True(r1)

r2 := Exists([]int{2, 4, 6, 8, 9}, func(x int) bool {
return x == 10
})
is.False(r2)
}