Reputation: 43153
Following the guides on generics and type constraints, I attempted to create an Array.without function as follows:
extension Array {
func without<T: Equatable>(item:T) -> T[] {
return self.map { $0 != item }
}
}
Testing this in a playground, I can't get it to work as the != value triggers a compiler error, "Could not find an overload for != that accepts the supplied arguments".
I believe the <T: Equatable>
should be enough to allow the use of !=
but obviously it didn't work. What's missing here?
Upvotes: 3
Views: 154
Reputation: 94803
The problem is that the T
you define in the method has nothing to do with the T
defined in the actual struct. Your local T
is constrained to be Equatable
, but the Array
version of T
is still not constrained and that is what self.map
is providing to the closure. The closure is getting an Array
type T
and you are trying to compare that to your local T
which isn't necessarily the same type.
I think the best you can do is something like this:
extension Array {
func without<U : Equatable>(item : U) -> [T] {
return self.filter { $0 as? U != item }
}
}
Unfortunately, this will still work if you call it with an instance of a different type as is stored in the array. If you do, it will simply return the original Array. It will not let you call it with an instance that is not equatable though.
Notes:
filter
instead of map
because that is the method that allows you to filter out contents of an array. map
is for changing contentswithout
to return an array. filter
and map
do not modify the array, instead they return a new version of the array that is altered according to the closure.Upvotes: 2