Is there no easy way to remove a specific element from an array, if it is equal to a given string? The workarounds are to find the index of the element of the array you wish
Using filter like suggested above is nice. But if you want to remove only one occurrence of a value or you assume there are no duplicates in the array and you want a faster algorithm, use this:
EDIT: Swift 5 Update
if let index = array.firstIndex(of: "stringToRemove") {
array.remove(at: index)
} else {
// not found
}
Thanks @Thomas Mary.
Swift 3 and 4
if let index = array.index(of: "stringToRemove") {
array.remove(at: index)
} else {
// not found
}
Simple loop over Array
var array = ["Apple","Banana","Orange"]
for (index,value) in array.enumerated(){
if value == "Banana"{
array.remove(at: index)
}
You'll want to use filter()
. If you have a single element (called say obj
) to remove, then the filter()
predicate will be { $0 != obj }
. If you do this repeatedly for a large array this might be a performance issue. If you can defer removing individual objects and want to remove an entire sub-array then use something like:
var stringsToRemove : [String] = ...
var strings : [String] = ...
strings.filter { !contains(stringsToRemove, $0) }
for example:
1> ["a", "b", "c", "d"].filter { !contains(["b", "c"], $0) }
$R5: [String] = 2 values {
[0] = "a"
[1] = "d"
}
var ra = ["a", "ab", "abc", "a", "ab"]
print(ra) // [["a", "ab", "abc", "a", "ab"]
ra.removeAll(where: { $0 == "a" })
print(ra) // ["ab", "abc", "ab"]
It's not clear if by quicker you mean in terms of execution time or amount of code.
In the latter case you can easily create a copy using the filter
method. For example, given the following array:
let array = ["1", "2", "3", "4", "5"]
you can create a copy with all elements but "2" as:
let filteredArray = array.filter { $0 != "2" }
You can use filter() to filter your array as follow
var strings = ["Hello","Playground","World"]
strings = strings.filter { $0 != "Hello" }
print(strings) // "["Playground", "World"]\n"
edit/update:
Xcode 10 • Swift 4.2 or later
You can use the new RangeReplaceableCollection
mutating method called removeAll(where:)
var strings = ["Hello","Playground","World"]
strings.removeAll { $0 == "Hello" }
print(strings) // "["Playground", "World"]\n"
If you need to remove only the first occurrence of an element we ca implement a custom remove method on RangeReplaceableCollection
constraining the elements to Equatable
:
extension RangeReplaceableCollection where Element: Equatable {
@discardableResult
mutating func removeFirst(_ element: Element) -> Element? {
guard let index = firstIndex(of: element) else { return nil }
return remove(at: index)
}
}
Or using a predicate for non Equatable
elements:
extension RangeReplaceableCollection {
@discardableResult
mutating func removeFirst(where predicate: @escaping (Element) throws -> Bool) rethrows -> Element? {
guard let index = try firstIndex(where: predicate) else { return nil }
return remove(at: index)
}
}
var strings = ["Hello","Playground","World"]
strings.removeFirst("Hello")
print(strings) // "["Playground", "World"]\n"
strings.removeFirst { $0 == "Playground" }
print(strings) // "["World"]\n"