The where
clause in for
loops currently allows us to test a certain condition while iterating a sequence to filter out the elements that don't satisfy that condition, which is cool because it lets us avoid nesting, i. e. instead of
let numbers: [Int] = [1, 4, 5, 2, 9, 13, 7, 14, 40, 11]
for number in numbers {
if isPrime(number) {
print("\(number) is prime")
}
}
we can write
let numbers: [Int] = [1, 4, 5, 2, 9, 13, 7, 14, 40, 11]
for number in numbers where isPrime(number) {
print("\(number) is prime")
}
However, I often find myself in need to filter out the elements that are nil
or have an optional property that is nil
, and somehow process the non-nil
values otherwise. Consider this example:
struct User {
var name: String
var birthday: DateComponents
var profilePic: UIImage?
var hasBirthdayToday: Bool { /* ... */ }
}
func addBirthdayCap(to profilePic: UIImage) { /* ... */ }
/* ... */
for user in users where user.hasBirthdayToday {
if let profilePic = user.profilePic {
addBirthdayCap(to: profilePic)
}
}
As you can see, we have a nested if
, the where
clause cannot help us in this case.
I propose to extend the syntax of where
clause everywhere except type constraints (see "Where "where" may be used?"), so that we could write
for user in users where user.hasBirthdayToday, let profilePic = user.profilePic {
addBirthdayCap(to: profilePic)
}
What do you think?