I'm trying to be more efficient with my code, but I'm having a brain fart. This code I wrote works great, and does exactly what I need it to do: It checks an array and removes an Object at an unknown Index. But I feel there is a better, more efficient way to write it. I went to Array.remove(at:) but that requires a known index. I'm getting into big O notation and don't know how to make this easier to process. Any ideas?
// create a new object array
var sort : [MyCustomObject] = []
//iterate through my object array
for i in objectArray{
if i === objectToRemove{
}
else{
sort.append(i)
}
}
// set old array to sort, which no longer has the unwanted object
self.objectArray = sort
If you want to remove an item from an array, you can use the pop() method to remove the last element or the shift() method to remove the first element.
To remove an element from the Swift Array, use array. remove(at:index) method.
Swift Array remove() The remove() method removes an element from the array at the specified index.
To remove a property from all objects in an array:Use the Array. forEach() method to iterate over the array. On each iteration, use the delete operator to delete the specific property.
Use firstIndex(where:)
(previously called index(where:)
in Swift 4.1 and earlier) to search the array for your object using the predicate { $0 === objectToRemove }
, then call remove(at:)
on the array to remove it:
if let idx = objectArray.firstIndex(where: { $0 === objectToRemove }) {
objectArray.remove(at: idx)
}
This allows you to search for your object whether it is Equatable
or not.
If you are coding with Xcode 10.0+ beta (Swift 4.2 or later) you can use the new method removeAll(where:)
mutating func removeAll(where predicate: (Element) throws -> Bool) rethrows
Discussion: Use this method to remove every element in a collection that meets particular criteria. Complexity: O(n), where n is the length of the collection.
This example removes all the odd values from an array of numbers:
Swift 5.2 or later
extension BinaryInteger {
var isEven: Bool { isMultiple(of: 2) }
var isOdd: Bool { !isMultiple(of: 2) }
}
var numbers = [5, 6, 7, 8, 9, 10, 11]
numbers.removeAll(where: \.isOdd) // numbers == [6, 8, 10]
numbers
In your case make sure MyCustomObject
conforms to Equatable
objectArray.removeAll(where: { $0 == objectToRemove })
or use one of its properties that does conform to it as the predicate (i.e id: Int
):
objectArray.removeAll(where: { $0.id == idToRemove })
Note: If you are not using Xcode 10.0+ beta (Swift 4.2) you can implement your own removeAll(where:)
method as you can see in this answer.
Implementing a removeFirst(where:)
and removeLast(where:)
to avoid iterating the whole Collection as mentioned in comments by @vacawama
Swift 4.1
extension RangeReplaceableCollection {
@discardableResult
mutating func removeFirst(where predicate: (Element) throws -> Bool) rethrows -> Element? {
guard let index = try index(where: predicate) else { return nil }
return remove(at: index)
}
}
extension RangeReplaceableCollection where Self: BidirectionalCollection {
@discardableResult
mutating func removeLast(where predicate: (Element) throws -> Bool) rethrows -> Element? {
guard let index = try indices.reversed().first(where: {
try predicate(self[$0])
}) else { return nil }
return remove(at: index)
}
}
Swift 4.2 or later (as suggested by @Hamish)
extension RangeReplaceableCollection {
@discardableResult
mutating func removeFirst(where predicate: (Element) throws -> Bool) rethrows -> Element? {
guard let index = try firstIndex(where: predicate) else { return nil }
return remove(at: index)
}
}
extension RangeReplaceableCollection where Self: BidirectionalCollection {
@discardableResult
mutating func removeLast(where predicate: (Element) throws -> Bool) rethrows -> Element? {
guard let index = try lastIndex(where: predicate) else { return nil }
return remove(at: index)
}
}
You can also check this post for a remove(while:), removeLast(while:) and dropLast(while:) method implementations.
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