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

时间:2017-07-11 08:52:53

标签: ios swift3 nspredicate

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

.EndsWith(".all")

我刚刚将我的objective-c代码转换为swift并尝试按此过滤。

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

但我总是将let exists = NSPredicate(format: "DisplayName2 CONTAINS[cd] \(searchText!)") let aList: Array<Any> = arrayDirectory.filter { exists.evaluate(with: $0) } if(aList.count>0) { arrayDirectory=aList facesCarousel.reloadData() } 计数为0.这似乎没有过滤我的数组。如何在swift 3中编写正确的aList并使用它过滤我的数组。

5 个答案:

答案 0 :(得分:5)

要在Swift中创建此过滤器,根本不需要NSPredicate

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

这应该是你所需要的一切。

修改

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

理想情况下,您不应该使用标准Dictionary作为工作对象。将您的词典数组转换为Structs数组。这样你就不需要串行输入你的代码或打开那些不是真正可选的属性。

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

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

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

答案 1 :(得分:4)

等同于ObjC代码的原生Swift是

"settings": {
        "analysis": {
        "analyzer": {
        "contact_section_start_analyzer": {
                "char_filter": "html_strip",
                "tokenizer": "contact_section_start_tokenizer"
        }
        },
        "tokenizer": {
        "contact_section_start_tokenizer": {
                "flags": "CASE_INSENSITIVE|DOTALL",
                "pattern": "\\b(annual\\s+report\\s+pursuant)\\b",
                "type": "pattern",
                "group": "1"
        }
        }
        }
        }

假设let filteredArray = arrayDirectory.filter { ($0["displayName2"] as! String).range(of: searchText!, options: [.diacriticInsensitive, .caseInsensitive]) != nil } 是原生的Swift arrayDirectory。它还会考虑Arraycase insensitive参数。

答案 2 :(得分:3)

你可以尝试

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

答案 3 :(得分:0)

使用此代码,我的代码可以帮助您

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()
 }

答案 4 :(得分:0)

使用此代码,我的工作正常,希望此代码可以帮助您

我有一个包含多个字典的数组。结构将是这样的

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

在上面的数组中,我使用苹果搜索控制器在谓词方法的帮助下使用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()
    }


}