如何在 swift 3 中使用 NSPredicate 过滤数组

How to filter an array using NSPredicate in swift 3

我有一个包含多个词典的数组。

{
   DisplayName?:"Name of the employee"
   Age:28
   Department:"Dept 2"
}

我刚刚将 objective-c 代码转换为 swift 并尝试像这样进行过滤。

let exists = NSPredicate(format: "DisplayName2 CONTAINS[cd] \(searchText!)")
    let aList: Array<Any> = arrayDirectory.filter { exists.evaluate(with: [=12=]) }
    if(aList.count>0)
    {
        arrayDirectory=aList
        facesCarousel.reloadData()
    }

但我总是将 aList 计数为 0。似乎没有过滤我的数组。如何在 swift 3 中编写正确的 NSPredicate 并使用它过滤我的数组。

你可以试试

self.arrayDirectory.filter({(([=10=]["Age"] as! String).localizedCaseInsensitiveContains(searchText))!})

要在 Swift 中制作此过滤器根本不需要 NSPredicate

let array = arrayDirectory.filter {
    guard let name = [=10=]["DisplayName"] as? String else {
        return false
    }
    return name.contains(searchText) 
}

这应该就是您所需要的。

编辑

已更新以匹配您的词典。我认为这就是你正在做的。

理想情况下,您不应使用标准 Dictionary 作为工作对象。将字典数组转换为结构数组。这样你就不需要严格地键入你的代码或解包不是真正可选的属性。

使用 [Any] 数组的解决方法...

因为您已将数组定义为 [Any](不要这样做),所以您需要先将对象转换为字典。

let array = arrayDirectory.filter {
    guard let dictionary = [=11=] as? [String: Any],
        let name = dictionary["DisplayName"] as? String else {
        return false
    }
    return name.contains(searchText) 
}

使用这个代码我的代码会帮助你

let predicate = NSPredicate(format: "DisplayName2 contains[c] %@", textField.text!)
 let arr : NSArray = arrayDirectory.filtered(using: predicate) as NSArray
 if arr.count > 0
 {
    arrayDirectory=arr
    facesCarousel.reloadData()
 }

原生Swift相当于ObjC代码是

let filteredArray = arrayDirectory.filter { ([=10=]["displayName2"] as! String).range(of: searchText!, options: [.diacriticInsensitive, .caseInsensitive]) != nil }

假设 arrayDirectory 是本地人 Swift Array。它还考虑了 case insensitivediacritic insensitive 参数。

使用这段代码在我这边工作得很好我希望这段代码对你有所帮助

我有一个数组,该数组包含多个字典。结构会是这样

 [
 {
  DisplayName:"Name of the employee1"
  Age:28
  Department:"Dept 2"
 }
 ]

在上面的数组中,我在谓词方法的帮助下使用 apple 搜索控制器使用 displayName 键进行过滤

  func updateSearchResults(for searchController: UISearchController) {

    if (searchController.searchBar.text?.characters.count)! > 0 {
        guard let searchText = searchController.searchBar.text, searchText != "" else {
            return
        }

        let searchPredicate = NSPredicate(format: "DisplayName CONTAINS[C] %@", searchText)

        usersDataFromResponse = (filteredArray as NSArray).filtered(using: searchPredicate)

        print ("array = \(usersDataFromResponse)")

        self.tableview.reloadData()
    }


}