Unable to filter array of dictionaries using predicate here is my code and i would like to filter array of dictionaries having key "category"
let searchText = searchTF.text?.replacingOccurrences(of: " ", with: "")
if (searchText?.characters.count)!>0 {
let pred = NSPredicate(format: "SELF beginswith[c] %#", searchTF.text!)
let array = NSMutableArray()
array.insert(dataArray as [AnyObject], at:NSIndexSet(indexesIn: NSMakeRange(0, dataArray.count)) as IndexSet)
dataArray.removeAllObjects()
getedArray = NSMutableArray(array: array.filtered(using: pred))
dataArray = getedArray.sortedArray(using: #selector(localizedCaseInsensitiveCompare(_ :)))
}
its giving error at last line i.e
getedArray = NSMutableArray(array: array.filtered(using: pred))
NSArray).sortedArrayUsingSelector(#selector(self.localizedCaseInsensitiveCompare))
its giving error at last line Use of unresolved identifier 'localizedCaseInsensitiveCompare'
Try this Swift native solution. filteredArray will contain the filtered and sorted array.
guard let searchText = searchTF.text, !searchText.isEmpty else { return }
let trimmedSearchText = searchText.replacingOccurrences(of: " ", with: "").lowercased()
let filteredArray = dataArray.filter( {($0["category"] as! String).lowercased().hasPrefix(trimmedSearchText) })
.sorted { ($0["category"] as! String).lowercased() < ($1["category"] as! String).lowercased() }
The code assumes that there is always a value for key category. Consider to use a custom struct or class to avoid the casts to String.
I have Achieved this by
let searchText = searchTF.text?.replacingOccurrences(of: " ", with: "")
if (searchText?.characters.count)!>0 {
// Put your key in predicate that is "category"
let searchPredicate = NSPredicate(format: "category CONTAINS[C] %#", searchText!)
let array = (dataArray as NSMutableArray).filtered(using: searchPredicate)
print ("array = \(array)")
if(array.count == 0){
searchTFActive = false;
} else {
searchTFActive = true;
}
self.aTable.reloadData()
}
Related
I have a variable declared as such:
private var theText = String()
private var aId = String()
I then do a fetch request and want to load it into that variable:
let predicateA = NSPredicate(format: "active == %#", true as CVarArg);
let predicateB = NSPredicate(format: "theId == %#", aId);
let andPredicate = NSCompoundPredicate(type: NSCompoundPredicate.LogicalType.and, subpredicates: [predicateA, predicateB]);
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext;
let requestData = NSFetchRequest<NSFetchRequestResult>(entityName: "DataTable");
requestData.predicate = andPredicate;
do
{
let results = try context.fetch(requestData);
dataactivitiesid = results.first
// let resultset = results as! [NSManagedObject];
/* for data in results
{
// let testyId: Any? = (data as AnyObject).value(forKey: "testyId");
} */
}
catch
{
print("Error in fetching data");
}
Do I need to loop through the result set like in the code that is commented above or since I know it is only one row being returned can I use .first? Thanks in advance.
If you expect only one item you don't need a loop.
I recommend to optional bind the result of first to a variable which can be nil if no entry is found.
And you don't need a compound predicate, a single predicate can contain multiple conditions related to the same object.
And finally this is not Objective-C, remove the trailing semicolons.
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext;
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "DataTable")
let predicate = NSPredicate(format: "active == TRUE AND theId == %#", aId)
fetchRequest.predicate = predicate
do {
if let result = try context.fetch(fetchRequest).first {
dataactivitiesid = result
}
} catch {
print(error) // print the actual error not a meaningless literal string
}
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 NSPredicatein swift 3 and filter my array using it.
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.
EDIT
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.
Workaround for working with an [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)
}
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.
you can try
self.arrayDirectory.filter({(($0["Age"] as! String).localizedCaseInsensitiveContains(searchText))!})
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()
}
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()
}
}
I have an array of dictionary, in which i need to search and return matching Dict
let foo = [
["selectedSegment":0, "severity":3, "dataDictKey": "critical"],
["selectedSegment":1, "severity":2, "dataDictKey": "major"],
["selectedSegment":2, "severity":1, "dataDictKey": "minor"],
]
In foo, how can i find for severity:2 and get matching Dict ?
Use the filter function
let foo = [
["selectedSegment":0, "severity":3, "dataDictKey": "critical"],
["selectedSegment":1, "severity":2, "dataDictKey": "major"],
["selectedSegment":2, "severity":1, "dataDictKey": "minor"],
]
let filteredArray = foo.filter{$0["severity"]! == 2}
print(filteredArray.first ?? "Item not found")
or indexOf
if let filteredArrayIndex = foo.indexOf({$0["severity"]! == 2}) {
print(foo[filteredArrayIndex])
} else {
print("Item not found")
}
or NSPredicate
let predicate = NSPredicate(format: "severity == 2")
let filteredArray = (foo as NSArray).filteredArrayUsingPredicate(predicate)
print(filteredArray.first ?? "Item not found")
Swift 3 Update:
indexOf( has been renamed to index(where:
filteredArrayUsingPredicate(predicate) has been renamed to filtered(using: predicate)
if let index = foo.flatMap({ $0["severity"] }).indexOf(2) {
print(foo[index])
}
Another way of doing it.
The first example only works if the user is 100% sure all the dictionaries contains "severity" as a key. To make it more safe:
if let index = foo.indexOf({ ($0["severity"] ?? 0) == 2 }) {
print(foo[index])
}
if you work on swift 3.1 -
let resultPredicate : NSPredicate = NSPredicate.init(format: "<your Key> CONTAINS [cd] %#", <value which you want to search>)
let filteredArray = requstData.arrayForColl?.filter { resultPredicate.evaluate(with: $0) };
I'm trying to filter an array with the first letter of name
I'm using this :
let predicate = NSPredicate(format: "name beginswith[c] %#", sections.objectAtIndex(section) as! String)
let sectionArray = self.mContacts.filteredArrayUsingPredicate(predicate)
Where section is :
let sections = NSArray(objects: "#","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z")
# must contain all the name begin by a digit.
But I can not filter the name begin by digit with this method.
I'm looking for some advices, thanks you
I solve this with MATCHES[c]
for sectionLetter in sections {
if (sectionLetter as! String) == "#" {
let predicateFormat = NSString(format: "name MATCHES[c] '[0-9].*'")
let predicate:NSPredicate = NSPredicate(format:predicateFormat as String)
let sectionArray = self.mContacts.filteredArrayUsingPredicate(predicate)
mSectionArray.addObject(sectionArray)
} else {
let predicateFormat = NSString(format: "name MATCHES[c] '(%#).*'", sectionLetter as! String)
let predicate:NSPredicate = NSPredicate(format:predicateFormat as String)
let sectionArray = self.mContacts.filteredArrayUsingPredicate(predicate)
mSectionArray.addObject(sectionArray)
}
}
The dictionary coming from server is
{
data = ({
email = "a123#gmail.com";
phone = 9804504884;
"user_id" = 11;
username = abcd;
});
}
var dataArray:NSArray = dict.objectForKey("data") as! NSArray
println("names = ,\(dataArray)");
var pre:NSPredicate = NSPredicate(format: "username CONTAINS[c] a")
var result:NSArray = dataArray.filteredArrayUsingPredicate(pre)
println("names = ,\(result)");
I am always getting result blank result array from this swift code.
Please help me to resolve this issue.
Thanks
Do it like this,
let json = try! NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.AllowFragments) as! NSDictionary
let predicate = NSPredicate(format: "username CONTAINS[C] 'a'")
if let filteredArray = json["data"]?.filteredArrayUsingPredicate(predicate) {
// do something with array
}
Note you should wrap your string inside single quotes ''.