Reputation: 3653
I have an arraycontaining several dictionaries.
{
DisplayName?:"Name of the employee"
Age:28
Department:"Dept 2"
}
I just converted my objective-c code into swift and trying to filter like this.
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()
}
But I am always getting the aList
count as 0. It seems like not filtering my array. How can I write proper NSPredicate
in swift 3 and filter my array using it.
Upvotes: 1
Views: 19230
Reputation: 989
Use this code its worked fine in my side I hope this code will be help you
I have an array that array containing several dictionaries. Structure will be like this
[
{
DisplayName:"Name of the employee1"
Age:28
Department:"Dept 2"
}
]
In above array i am filtering with displayName key using apple search controller with help of predicate method
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()
}
}
Upvotes: 0
Reputation: 77621
To make this filter in Swift doesn't require NSPredicate
at all.
let array = arrayDirectory.filter {
guard let name = $0["DisplayName"] as? String else {
return false
}
return name.contains(searchText)
}
That should be all you need.
Updated to match your dictionary. I think this is what you're doing.
Ideally, you shouldn't be using a standard Dictionary
as a working object. Convert your array of dictionaries to an array of Structs. That way you don't need to stringly type your code or unwrap properties that aren't really optional.
[Any]
array...Because you have defined your array as [Any]
(don't do this) you will need to convert the object to a dictionary first.
let array = arrayDirectory.filter {
guard let dictionary = $0 as? [String: Any],
let name = dictionary["DisplayName"] as? String else {
return false
}
return name.contains(searchText)
}
Upvotes: 6
Reputation: 285059
The native Swift equivalent to the ObjC code is
let filteredArray = arrayDirectory.filter { ($0["displayName2"] as! String).range(of: searchText!, options: [.diacriticInsensitive, .caseInsensitive]) != nil }
assuming arrayDirectory
is a native Swift Array
. It considers also the case insensitive
and diacritic insensitive
parameters.
Upvotes: 4
Reputation: 641
Use this code my code will help you
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()
}
Upvotes: 0
Reputation: 5053
you can try
self.arrayDirectory.filter({(($0["Age"] as! String).localizedCaseInsensitiveContains(searchText))!})
Upvotes: 4