Syntactic-sugar: exclude
I am a fan of higher order functions in Swift, allowing for mapping, filtering, and reducing on sequences - like in the following example:
let points = [1.0, 1.5, -3.8, 0.5]
let positive = points.filter { $0 > 0 }
print(positive)
The above code will print: [1.0, 1.5, 0.5]
because those are the doubles above 0. This is because of the closure given to filter()
, and even though $0 > 0
can be easy to read, closures can become complex, why often declare them as a function:
func isPositive(_ number: Double) -> Bool {
return number > 0
}
let points = [1.0, 1.5, -3.8, 0.5]
let positive = points.filter(isPositive)
print(positive)
Easy. But now, what if I wanted to get all the negative numbers? There is a couple of solutions:
- I could create a corresponding
isNegative(double) -> Bool
function, but thinking about it, I would have to follow this pattern of creating a sorting function for both including and excluding on each parameter. - I could take a step back, and provide the filter with a closure:
points.filter { !isPositive($0) }
, but that again can become complex.
Exclude() - the long lost brother
That is why I created this little extension, which does the opposite of the filter function:
extension Sequence {
func exclude(_ predicate: (Self.Element) throws -> Bool) rethrows -> [Self.Element] {
return try self.filter { try !predicate($0) }
}
}
We can see that it simply wraps a negation of filter, why it is syntactic sugar, but it allows us to now do the following:
let points = [1.0, 1.5, -3.8, 0.5]
let negative = points.exclude(isPositive)
print(negative)
Which I think is pretty neat.