Swift Closure / Lambda with Substitution Variables
Remember Objective-C, where you can use filteredArrayUsingPredicate
on a NSArray
in conjunction with a NSPredicate
? Then you also remember, that it is possible to use substitution variables in the predicate which come in handy, when you have to re-use it in different methods.
In Swift, nothing blocks us from doing the same. However, using the built-in filter
is more appealing. For example, consider the following data structure (initializers not shown):
class A
{
let X : Int
let Y : Int
}
Further, there is some function fun
which returns an array of A
, e.g. func getArray() -> [ A ]
. Now, in order to filter the array, we can use filter
and a closure (lambda):
var As = getArray()
As.filter({ (a: As) -> Bool in return (a.X == 0 && a.Y == 1) })
Since it is a closure, it can capture variables from outside, so we can replace the hardcoded 0 and 1 by a variable:
var As = getArray()
let x = 0
let y = 1
let Bs = As.filter({ (a: A) -> Bool in return (a.X == x && a.Y == y) })
// Do something with Bs
Now, the question is: how to re-use this lambda with a different set of x
and y
. Then answer is quite easy: make yourself a helper function! For example:
func makePredicate(#x: Int, #y: Int) -> (A -> Bool)
{
return { (a: A) -> Bool in return a.X == x && a.Y == y }
}
This small function returns a lambda with captured variables x
and y
. You can call it directly with filter
:
let Bs = As.filter(makePredicate(x: 0, y: 1))
This also works with every other function like map
or sort
. Happy filtering!