Abhishek Bedi
Abhishek Bedi

Reputation: 5451

Swift Generics : Custom closure with multiple arguments for filter function

I have an caching array which can store different types of objects like UIViews, UICollectionReuableView, etc

var arrCache             = [AnyObject]()

I want to filter out these specific elements using built in filter function by passing a custom closure like this :

private func reusableViewsClosure<T where T: Equatable>(element : AnyObject, type: T) -> Bool {
    return element is T ? true : false
}

Now, when I call this closure on the filter function, I get an error stating

        let i = arrCache.filter(reusableViewsClosure(UIView))

// error: Cannot convert call result type bool to expected type '(@noescape (Anyobject) throws -> Bool)'

Just wondering if it is allowed to pass extra parameters for closures used for built in functions like map,flatmap, filter, etc because when I call the same function like this below, it works just fine:

private func reusableHeaderViewsClosure(element : AnyObject) -> Bool {
    return element is UICollectionReusableView ? true : false
}
...
let i = arrCache.filter(reusableHeaderViewsClosure)

Upvotes: 3

Views: 873

Answers (1)

Tomasz Bąk
Tomasz Bąk

Reputation: 6204

At the moment syntax for this case will look like this:

let i = arrCache.filter { reusableViewsClosure($0, UIView) }

or a little more descriptive:

let i = arrCache.filter { object in
  return reusableViewsClosure(object, UIView)
}

I prefer first option for its compact size. If you really want to use filer(closure) syntax you can create factory returning closure (function currying).

func factory<T where T: Equatable>(type: T.Type) -> (AnyObject -> Bool) {
    return { reusableViewsClosure($0, type) }
}

with this you can use it for filter:

let i = arrCache.filter (factory(UICollectionView))

Upvotes: 1

Related Questions