【问题标题】:Remove Specific Array Element, Equal to String - Swift删除特定的数组元素,等于字符串 - Swift
【发布时间】:2015-03-08 20:24:38
【问题描述】:

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

【问题讨论】:

  • 您是否查看过 NSMutableArray 类参考中的方法,例如 removeObject: 或 removeObjectIdenticalTo:?
  • 我正在使用 swift,而我发现我可以对数组做什么的方法是在其名称后放置一个点,然后查看 xcode 建议的选项,这些选项包括 removeAll、removeAtIndex、removeLast、并删除范围。我看不到任何对 removeObjectIdenticalTo 的引用。
  • 您的问题没有具体说明您是指 Swift Array 还是 NSMutableArray;你可以在 Swift 中使用以太。如果您使用 Swift 编程,除非您将数组转换为 NSMutableArray,否则您不会看到 NSMutableArray 建议
  • 谢谢,我一个月前才开始编程,非常有帮助

标签: ios iphone arrays swift elements


【解决方案1】:

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

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

strings = strings.filter { $0 != "Hello" }

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

编辑/更新:

Xcode 10 • Swift 4.2 或更高版本

您可以使用称为removeAll(where:) 的新RangeReplaceableCollection 变异方法

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

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

【讨论】:

    【解决方案2】:

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

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

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

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

    let filteredArray = array.filter { $0 != "2" }
    

    【讨论】:

    • 哈哈哈我们完美同步,但我快了 7 秒。 :)
    • @LeonardoSavioDabus:哈哈,是的,但是我在写答案的时候被我妻子问了一个问题打断了我……所以我赢了 ;-)
    • 谢谢,我想这基本上就是我一直在做的,通过使用 for 循环遍历数组并将元素附加到另一个数组,如果它不等于我希望删除的字符串,当我说得更快时,你是对的,我的意思是在我的代码中看起来更整洁。谢谢!
    【解决方案3】:

    您需要使用filter()。如果您要删除单个元素(称为obj),则filter() 谓词将为{ $0 != obj }。如果您对大型阵列重复执行此操作,这可能是一个性能问题。如果您可以推迟删除单个对象并希望删除整个子数组,请使用以下内容:

    var stringsToRemove : [String] = ...
    var strings : [String] = ...
    
    strings.filter { !contains(stringsToRemove, $0) }
    

    例如:

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

    【讨论】:

      【解决方案4】:

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

      func -= (inout left: [String], right: String){
          left = left.filter{$0 != right}    
      }
      
      var myArrayOfStrings:[String] = ["Hello","Playground","World"]
      
      myArrayOfStrings -= "Hello"
      
      print(myArrayOfStrings)   // "[Playground, World]"
      

      【讨论】:

        【解决方案5】:

        如果您需要从数组中删除 subArray,那么这是使用 Swift3 的完美解决方案:

        var array = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]            
        let subArrayToDelete = ["c", "d", "e", "ee"]
        array = array.filter{ !subArrayToDelete.contains($0) }
        print(array) // ["a", "b", "f", "g", "h", "i", "j"]
        

        这样对你的表现更好,而不是一个一个地删除。

        btw 甚至 faster 解决方案是(但它会重新排列最终数组中的项目):

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

        【讨论】:

          【解决方案6】:

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

          编辑: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
          }
          

          【讨论】:

          • Swift 5 更新:if let index = array.firstIndex(of: "stringToRemove") { array.remove(at: index) }
          【解决方案7】:
          var ra = ["a", "ab", "abc", "a", "ab"]
          
          print(ra)                               // [["a", "ab", "abc", "a", "ab"]
          
          ra.removeAll(where: { $0 == "a" })
          
          print(ra)                               // ["ab", "abc", "ab"]
          

          【讨论】:

          • 这个和removeAll { $0 == "a" }一模一样
          【解决方案8】:

          数组的简单循环

          var array = ["Apple","Banana","Orange"]
          
          for (index,value) in array.enumerated(){
              if value == "Banana"{
              array.remove(at: index)
          }
          

          【讨论】:

          • 您无法从非可变集合中删除项目
          • 感谢 Buddy @LeoDabus 纠正我我已经从 let 更改为 var 现在你可以做到了
          猜你喜欢
          • 2019-05-02
          • 1970-01-01
          • 2022-01-12
          • 2018-12-31
          • 2015-06-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-10-21
          相关资源
          最近更新 更多