Search in Array of Dictionaries by key name - ios

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

Related

How to filter an array using NSPredicate in swift 3

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

Swift 3 filterWithPredicate not working

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

Sorting of an array alphabetically in swift

I am new to swift.I am trying one sample app in which I need to implement the sorting of an array in alphabetical order.I getting the json data and I am adding the titles in the array.Now i would like to sort that alphabetically.Here is my code .....
func updateSearchResults(data: NSData?)
{
do
{
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments)
if let blogs: NSArray = json["results"] as? [AnyObject] {
print(blogs)
for blog in blogs {
if let name = blog["original_title"] as? String {
names.addObject(name)
}
}
print(names)
**let sortedArray = sorted(names, {
(str1: String, str2: String) -> Bool in
return str1.toInt() < str2.toInt()** // Here I am getting the Error Message
})
}
}
catch {
print("error serializing JSON: \(error)")
}
}
The error message I am getting is "Cannot invoke 'sorted' with an argument list of type '(NSMutableArray, (String, String) -> Bool)'"
I tried a lot to achieve this but I didn't find the solution.
Can anyone help me to resolve this issue.
Thanks In Advance.
First convert NSMutableArray to the Array by using below line of code.
let swiftArray = mutableArray as AnyObject as! [String]
Use below line of code to sort the Array.
var sortedArray = names.sorted { $0.localizedCaseInsensitiveCompare($1) == NSComparisonResult.OrderedAscending }
Check below link for sort Closures.
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Closures.html
Update for Swift 3.0
var sortedArray = swiftArray.sorted { $0.localizedCaseInsensitiveCompare($1) == ComparisonResult.orderedAscending }
Use this simple code of line to sort ur array
let sortedNames = names.sort { $0.name < $1.name }
For Swift 4 you can use only this
let sortedNames = names.sorted(by: <)
Swift4
var names = [ "Alpha", "alpha", "bravo", "beta"]
var sortedNames = names.sorted { $0.localizedCaseInsensitiveCompare($1) == ComparisonResult.orderedAscending }
print(sortedNames) //Logs ["Alpha", "alpha","beta", "bravo"]
Swift 4(working code)
JSON response -> Stored in aryNameList
"DATA": [
{
email = "iosworker#gmail.com";
firstname = Harvey
},
{
email = "poonam#openxcell.com";
firstname = poonam
},
{
email = "t#t.com";
firstname = rahul
},
{
email = "android.testapps#gmail.com";
firstname = Chulbulx
},
{
email = "t#t2.com";
firstname = rahul
},
{
email = "jaystevens32#gmail.com";
firstname = Jay
},
{
email = "royronald47#gmail.com";
firstname = Roy
},
{
email = "regmanjones#hotmail.com";
firstname = Regan
},
{
email = "jd#gmail.com";
firstname = Jaydip
}
]
Code
self.aryNameList = self.aryNameList.sorted(by: { (Obj1, Obj2) -> Bool in
let Obj1_Name = Obj1.firstname ?? ""
let Obj2_Name = Obj2.firstname ?? ""
return (Obj1_Name.localizedCaseInsensitiveCompare(Obj2_Name) == .orderedAscending)
})
working every case (for ex: lowerCase, upperCase..)
For an array of objects:
items = items.sorted(by: { (item1, item2) -> Bool in
return item1.product.name.compare(item2.product.name) == ComparisonResult.orderedAscending
})
Try this one
var names = [ "Alpha", "alpha", "bravo"]
var sortedNames = names.sort { $0.localizedCaseInsensitiveCompare($1) == NSComparisonResult.OrderedAscending }
print(sortedNames) //Logs ["Alpha", "alpha", "bravo"]
Swift 3 solution:
let yourStringArray = [ "beTA", "ALPha", "Beta", "Alpha"]
var sortedArray = yourStringArray.sorted()
// Result will be ["ALPha", "Alpha", "Beta", "beTA"]
Creds to jjatie

Filter AnyObject in Swift 2

I have an JsonArray named data which I pass to AnyObject:
if let dtMenu: AnyObject = responseObject?.valueForKey("data") {
print(filteredMenu)
}
// I got JsonArray here
// My data are
"data":[
{
"MENUITEMID":1.0,
"MENUITEMNAMEENG":"IGW",
"MENUITEMHREF":"IGW_1",
"MENUITEMTYPE":"R",
"MENUITEMLEVEL":1.0,
"MENUGRPID":0.0,
"MENUGRPSERIAL":1.0
},
{
"MENUITEMID":6.0,
"MENUITEMNAMEENG":"Dashboard",
"MENUITEMHREF":"Dashboard_IGW",
"MENUITEMTYPE":"L",
"MENUITEMLEVEL":2.0,
"MENUGRPID":1.0,
"MENUGRPSERIAL":1.0
}]
//I want to filter array by MENUITEMTYPE=R
Please help..
Try this.
var predicate = NSPredicate(format: "%K == %#", "MENUITEMTYPE", "R")
let filteredArray = yourArray.filter { predicate.evaluateWithObject($0) };
I have not tested this yet.

NSPredicate filter array with first character

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

Resources