Swift过滤器字符串数组

Posted

技术标签:

【中文标题】Swift过滤器字符串数组【英文标题】:Swift filter array of strings 【发布时间】: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 的子类型” 以下任一答案是否回答了您的问题? 【参考方案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"]

以上是关于Swift过滤器字符串数组的主要内容,如果未能解决你的问题,请参考以下文章

过滤和排序 swift 数组

swift 3通过字典中键的字符串值过滤字典数组

如何在 iOS swift 中使用文本字段过滤日期数组?

在 Swift 中过滤对象数组并求和它们的属性

在Swift中使用Realm进行过滤,给我一个对象数组,但是当打印一个属性时,它会给我一个空字符串

在 swift 中使用 tableview 和数组过滤器自动完成文本字段