【问题标题】:Swift filter array of stringsSwift过滤器字符串数组
【发布时间】:2015-06-09 11:39:43
【问题描述】:

我在快速过滤关键字(字符串)数组时遇到了麻烦,我的代码:

self.filteredKeywords=filter(keywords.allValues, {(keyword:NSString) ->                                              
  Bool in
    let words=keyword as? NSString
    return words?.containsString(searchText)
  })

由于AnyObject 不能是NSString 的子类型,所以我被困住了!

【问题讨论】:

  • 您得到的确切错误是什么?如果您尝试NSLog("\(keywords)"),会打印什么?
  • 请注意,您正在返回一个可选项。希望这会有所帮助
  • 它没有运行它给我上面提到的错误:“AnyObject 不是 NSString 的子类型”
  • 以下任一答案是否回答了您的问题?

标签: ios arrays string swift filtering


【解决方案1】:

[为 Swift 2.0 更新]

由于NSString 是免费桥接到 Swift String,因此请避免以下强制:

  3> ["abc", "bcd", "xyz"].filter() { nil != $0.rangeOfString("bc") }
$R1: [String] = 2 values {
  [0] = "abc"
  [1] = "bcd"
}

但是,如果您认为 allValues 不是字符串:

(keywords.allValues as? [String]).filter() { nil != $0.rangeOfString("bc") }

返回一个可选数组。

【讨论】:

    【解决方案2】:

    您的filter 已结束[AnyObject],但您的关闭需要NSString。这些需要匹配。此外,您的结果必须是Bool,而不是Bool?。您可以像这样简单地解决这些问题:

    self.filteredKeywords = filter(keywords.allValues, {
        let keyword = $0 as? NSString
        return keyword?.containsString(searchText) ?? false
    })
    

    这接受AnyObject,然后尝试将其强制转换为NSString。然后它 nil-coalleces (??) 结果以确保它始终是 Bool

    不过,我建议将keywords 视为[String:String] 而不是NSDictionary。这将摆脱AnyObject 的所有复杂性。然后你可以这样做:

    self.filteredKeywords = keywords.values.filter { $0.rangeOfString(searchText) != nil }
    

    只要有可能,尽快将 Foundation 集合转换为 Swift 集合并存储它们。如果您有传入的 Foundation 对象,您通常可以使用以下技术轻松转换它们:

    let dict = nsdict as? [String:String] ?? [:]
    

    或者您可以执行以下操作来转换它们,以便它们在调试时崩溃(但在发布时静默“工作”):

    func failWith<T>(msg: String, value: T) -> T {
        assertionFailure(msg)
        return value
    }
    
    let dict = nsdict as? [String:String] ?? failWith("Couldn't convert \(d)", [:])
    

    【讨论】:

      【解决方案3】:

      Swift 4.2 提供了一种新方法:

      var theBigLebowski = ["The Dude", "Angry Walter", "Maude Lebowski", "Donny Kerabatsos", "The Big Lebowski", "Little Larry Sellers"]
      
      // after removeAll -> ["The Dude", "Angry Walter", "Donny Kerabatsos", "Little Larry Sellers"]
      theBigLebowski.removeAll{ $0.contains("Lebowski")}
      print(theBigLebowski)
      

      【讨论】:

        【解决方案4】:

        GoZoner 对某些数据类型的回答既存在问题,也有更好的方法来做到这一点。下面的例子可以说明这一点:

        let animalArray: NSMutableArray = ["Dog","Cat","Otter","Deer","Rabbit"]
        let filteredAnimals = animalArray.filter { $0.rangeOfString("er") != nil }
        print("filteredAnimals:", filteredAnimals)
        
        filteredAnimals: [Dog, Cat, Otter, Deer, Rabbit]
        

        可能不是你所期望的!

        但是,如果我们不将 animalArray 键入为 NSMutableArray,这样就可以正常工作:

        let animalArray = ["Dog","Cat","Otter","Deer","Rabbit"]
        let filteredAnimals = animalArray.filter { $0.rangeOfString("er") != nil }
        print("filteredAnimals:", filteredAnimals)
        
        filteredAnimals: [Otter, Deer]
        

        但是我建议使用 $0.contains() 而不是 $0.rangeOfString() != nil,因为它在这两种情况下都有效并且稍微提高了代码的可读性:

        let animalArray: NSMutableArray = ["Dog","Cat","Otter","Deer","Rabbit"]
        let filteredAnimals = animalArray.filter { $0.contains("er") }
        print("filteredAnimals:", filteredAnimals)
        
        filteredAnimals: [Otter, Deer]
        

        【讨论】:

        • 如果您有一组过滤器(例如 mime 类型)应用于字符串,而不是仅过滤一个字符串(例如“er”),该怎么办? filter=["stuff", "bear", "bottle"]
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-15
        • 1970-01-01
        • 2022-07-04
        • 1970-01-01
        相关资源
        最近更新 更多