I have places where I have both Set
and Array
of MyType
.
In these places, I need to filter down my Sequences
, and you'll notice that the filter
block is the same for both Sequence
types.
Is there any way I can implement a generic Sequence
extension, where the filterFor
method will return the correct type (Set
or Array
), depending on the receiver?
extension Set where Element: MyType {
func filterFor(valueToMatch:String) -> Set<MyType> {
return self.filter{
$0.myProperty.caseInsensitiveCompare(valueToMatch) == .orderedSame
}
}
}
extension Array where Element: MyType {
func filterFor(valueToMatch:String) -> [MyType] {
return self.filter{
$0.myProperty.caseInsensitiveCompare(valueToMatch) == .orderedSame
}
}
}
Unfortunately, no. Set
has two overloads of filter(_:)
, with these types:
func filter(_ isIncluded: (Self.Element) throws -> Bool) rethrows -> [Self.Element]
func filter(_ isIncluded: (Self.Element) throws -> Bool) rethrows -> Set<Self.Element>
The first is the implementation that satisfies the requirements of conformance to Sequence
. The latter is just a method that Set
implements, that isn't tied to any protocol.
There is no generic way to reference a variant of Filter
that returns anything besides Array<Self.Element>
. There is a Swift Evolution proposal to fix this (SE-0174 - Change filter to return an associated type). It has been accepted, but has not been implemented yet.