Reputation: 41226
I have a function that is currently defined as:
public func mappingsWithElementId(elementId:String) -> [Mapping] {
return _mappings.lazy.map({ $1 }).filter({ $0.elementId == elementId })
}
I would like to change it so that rather than return an array, it just returns a (lazy) object that can be iterated, i.e., a CollectionType<Mapping>
that the caller can then use however is appropriate.
Now, I can use:
public func mappingsWithElementId(elementId:String) -> LazyFilterCollection<LazyMapCollection<[String:Mapping], Mapping>> {
return _mappings.lazy.map({ $1 }).filter({ $0.elementId == elementId })
}
But that's way overly specific for what I'm attempting to do (which is just tell the caller that it's something that can be iterated to get Mapping
s. And as I cascade more functions of a similar nature it just gets uglier and uglier.
Is there a way that I can declare my function which simply promises to return something that can be iterated as a CollectionType<Mapping>
?
Trying to use CollectionType<Mapping>
yields:
Cannot specialize non-generic type 'CollectionType'
Trying to use CollectionType
gives me the error that:
Protocol 'CollectionType' can only be used as a generic constraint because it has Self or associated type requirements
Upvotes: 1
Views: 87
Reputation: 299355
This is what type erasers are for. In this case you're looking for AnyForwardCollection
:
public func mappingsWithElementId(elementId:String) -> AnyForwardCollection<Mapping> {
return AnyForwardCollection(_mappings.lazy.map({ $1 }).filter({ $0.elementId == elementId }))
}
There are a bunch of others. AnySequence
, AnyRandomAccessCollection
, etc. You can create your own if you like, as well. See A Little Respect for AnySequence for more on that.
Upvotes: 3