I am attempting to create an extension method for the Array type to allow for removing an item from an array
extension Array {
func remove(item: AnyObject) {
for var i = self.count - 1; i >= 0; i-- {
if self[i] == item {
self.removeAtIndex(i)
}
}
}
}
On the test condition if self[i] == item
, I get the following error: 'T' is not convertible to 'MirrorDisposition'
I've tried many different things, which include:
- Using generics:
remove<T>(item: T)
- Using the
===
operator, which just gives the error 'T' does not conform to protocol 'AnyObject'
I'm new to Swift, so this is where my knowledge runs out. Any suggestions would be greatly appreciated.
You are getting an error because the compiler can't guarantee that the element stored in your array can be compared with ==
. You have to ensure that it the contained type is Equatable
. However, there is no way to add a method to a generic class that is more restrictive than the class itself. It is better to implement it as a function:
func removeItem<T: Equatable>(item: T, var fromArray array: [T]) -> [T] {
for i in reverse(0 ..< array.count) {
if array[i] == item {
array.removeAtIndex(i)
}
}
return array
}
Or you could add it as a more generic extension:
extension Array {
mutating func removeObjectsPassingTest(test: (object: T) -> Bool) {
for var i : Int = self.count - 1; i >= 0; --i {
if test(object: self[i]) {
self.removeAtIndex(i)
}
}
}
}
Then you can do this:
var list: [Int] = [1,2,3,2,1]
list.removeObjectsPassingTest({$0 == 2})
The way I would write this function is like this:
mutating func remove<U where U : Equatable>(item: U) {
for var i = self.count - 1; i >= 0; i-- {
if self[i] as U == item {
self.removeAtIndex(i)
}
}
}
Be sure to decorate your function with mutating.
I would use a different type parameter U since you can't really change Array's type parameter to be Equatable. Then I would try to cast the items to U to do the comparison.
Of course, this will fail if you try to call this function with an Array that is instantiated with a non-equatable type.
This is not a solution but if you are trying to remove an item from an array, this is how I do it:
var numbers = [1, 2, 3, 4, 5]
if let possibleIndex = find(numbers, 1) {
numbers.removeAtIndex(possibleIndex)
}
The error message is confusing. The problem why it does not work is because Swift compiler can not find ==
operator for Array's element type T
. For this to work T
would need to conform to Equatable
protocol.
I don't know what is MirrorDispsition, but I think the problem is that you can't always equate two objects in Array, because they are not guaranteed to be equatable.
Edit: Look at tng's solution. It will only work with equatable items, though.