删除特定数组元素,等于字符串 - Swift

Remove Specific Array Element, Equal to String - Swift

是否没有简单的方法可以从数组中删除特定元素(如果它等于给定字符串)?变通方法是找到要删除的数组元素的索引,然后 removeAtIndex,或者创建一个新数组,在其中追加所有不等于给定字符串的元素。但是有没有更快捷的方法呢?

您可以使用 filter() 来过滤您的数组,如下所示

var strings = ["Hello","Playground","World"]

strings = strings.filter { [=10=] != "Hello" }

print(strings)   // "["Playground", "World"]\n"

edit/update:

Xcode 10 • Swift 4.2 或更高版本

您可以使用名为 removeAll(where:)

的新 RangeReplaceableCollection 变异方法
var strings = ["Hello","Playground","World"]

strings.removeAll { [=11=] == "Hello" }

print(strings)   // "["Playground", "World"]\n"

如果您只需要删除第一次出现的元素,我们可以在 RangeReplaceableCollection 上实施自定义删除方法,将元素限制为 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)
    }
}

或对非 Equatable 元素使用谓词:

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 { [=14=] == "Playground" }
print(strings)   // "["World"]\n"

不清楚您所说的更快是指执行时间还是代码量。

在后一种情况下,您可以使用 filter 方法轻松创建副本。例如,给定以下数组:

let array = ["1", "2", "3", "4", "5"]

您可以使用除“2”以外的所有元素创建一个副本:

let filteredArray = array.filter { [=11=] != "2" }

您需要使用 filter()。如果要删除单个元素(称为 obj),则 filter() 谓词将为 { [=15=] != obj }。如果您对大型阵列重复执行此操作,则可能会出现性能问题。如果您可以推迟删除单个对象并希望删除整个子数组,请使用类似:

var stringsToRemove : [String] = ...
var strings : [String] = ...

strings.filter { !contains(stringsToRemove, [=10=]) }

例如:

 1> ["a", "b", "c", "d"].filter { !contains(["b", "c"], [=11=]) }
$R5: [String] = 2 values {
  [0] = "a"
  [1] = "d"
}

您可以结合使用 filter() 和运算符重载来生成易于重复的解决方案:

func -= (inout left: [String], right: String){
    left = left.filter{[=10=] != right}    
}

var myArrayOfStrings:[String] = ["Hello","Playground","World"]

myArrayOfStrings -= "Hello"

print(myArrayOfStrings)   // "[Playground, World]"

如果您需要从数组中删除子数组,那么这是使用 Swift3:

的完美解决方案
var array = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]            
let subArrayToDelete = ["c", "d", "e", "ee"]
array = array.filter{ !subArrayToDelete.contains([=10=]) }
print(array) // ["a", "b", "f", "g", "h", "i", "j"]

这比一个一个地删除对你的表现更好。

顺便说一句,甚至 更快 解决方案是(但它会重新排列最终数组中的项目):

array = Array(Set(array).subtracting(subArrayToDelete))

像上面建议的那样使用过滤器很好。但是如果你只想删除一个值的一次出现或者你假设数组中没有重复项并且你想要一个更快的算法,请使用这个:

编辑:Swift 5 次更新

if let index = array.firstIndex(of: "stringToRemove") {
    array.remove(at: index)
} else {
    // not found
}

谢谢@Thomas Mary。

Swift 3 和 4

if let index = array.index(of: "stringToRemove") {
    array.remove(at: index)
} else {
    // not found
}
var ra = ["a", "ab", "abc", "a", "ab"]

print(ra)                               // [["a", "ab", "abc", "a", "ab"]

ra.removeAll(where: { [=10=] == "a" })

print(ra)                               // ["ab", "abc", "ab"]

数组的简单循环

var array = ["Apple","Banana","Orange"]

for (index,value) in array.enumerated(){
    if value == "Banana"{
    array.remove(at: index)
}