Adding anySatisfy, noneSatisfy to Sequence
Introduction
I propose to add two methods to Sequence
anySatisfy
noneSatisfy
Motivation
anySatisfy
: we need to determine whether a sequence meets a condition by iterating each element until one meets the predicate. When an element meets the predicate, the iteration exits early.
noneSatisfy
: we need to determine whether a sequence meets a condition by iterating every element and testing a predicate. When an element does not meet the predicate, the iteration exits early.
Proposed solution
public extension Sequence {
func anySatisfy(_ predicate: (Element) throws -> Bool) rethrows -> Bool {
for element in self {
if try predicate(element) { return true }
}
return false
}
func noneSatisfy(_ predicate: (Element) throws -> Bool) rethrows -> Bool {
try !anySatisfy(predicate)
}
}
This allows to write efficient, readable code like this:
struct Item {
var inProgress: Bool
}
func test_item_sequence_is_in_progress() {
var items = [Item](repeating: .init(inProgress: false), count: 10)
let randomIndex = (0..<items.count).randomElement()!
items[randomIndex].inProgress = true
let itemsInProgress = items.anySatisfy(\.inProgress)
XCTAssert(itemsInProgress)
}
func test_item_sequence_not_started() {
let items = [Item](repeating: .init(inProgress: false), count: 10)
let itemsComplete = items.noneSatisfy(\.inProgress)
XCTAssert(itemsComplete)
}
func test_item_sequence_complete() {
let items = [Item](repeating: .init(inProgress: true), count: 10)
let itemsComplete = items.allSatisfy(\.inProgress)
XCTAssert(itemsComplete)
}