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?
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.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With