NSPredicate filter array with first character - ios

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

Related

Loading the results set for Core Data fetch request

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
}

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

Search in Array of Dictionaries by key name

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

Having trouble in filter array of dictionaries coming from server in swift

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 ''.

Searching through objects in array swift

I'm trying to create a search function using the UISearchController. However i cant seem to make it work with my Team Object. I've started by creating a Team Object which contain a id, name and shortname. Then i'm retrieving the teamData from a url and adding the Team Objects into an array which is populated into a tableView. This tableView contain a searchController which is suppose to filter the Data, but nothing happens.
arrays
var teamArray = Array<Team>()
var filteredTableData = [String]()
GetTeams function
func getTeams(url: String) {
isApiCalling = true
request(.GET, url, parameters: nil)
.response { (request, response, data, error) in
if error == nil {
let data: AnyObject = data!
let jsonArray = JSON(data: data as! NSData)
for (key: String, subJson: JSON) in jsonArray {
// Create an object and parse your JSON one by one to append it to your array
var newTeamObject = Team(id: subJson["id"].intValue, name: subJson["name"].stringValue, shortname: subJson["shortname"].stringValue)
self.teamArray.append(newTeamObject)
}
self.isApiCalling = false
self.tableView.reloadData()
self.refreshControl?.endRefreshing()
}
}
}
CellForRowAtIndexPath
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("teamCell", forIndexPath: indexPath) as! TeamCell
cell.textLabel?.font = UIFont(name: "HelveticaNeue-Light", size: 20)
cell.textLabel?.text = self.teamArray[indexPath.row].name as String
if (self.cellSelected.containsObject(indexPath)) {
cell.accessoryView = cell.accessoryCheck
} else {
cell.accessoryView = cell.accessoryUncheck
}
return cell
}
FilterData
func updateSearchResultsForSearchController(searchController: UISearchController)
{
filteredTableData.removeAll(keepCapacity: false)
let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %#", searchController.searchBar.text)
let array = (teamArray as NSArray).filteredArrayUsingPredicate(searchPredicate)
filteredTableData = array as! [String]
self.tableView.reloadData()
}
Team Objects
class Team{
var id: Int!
var name: NSString!
var shortname: NSString!
init(id: Int, name:NSString, shortname: NSString) {
self.id = id
self.name = name
self.shortname = shortname
}
}
The objects in the teamArray don't have a SELF property. You can't use SELF to search in all the properties of the object at once. You have to give the name of the property, and if you want to search in more than one you have to add all those properties to the predicate.
I would think it's enough for you to search in the name property like so:
let searchPredicate = NSPredicate(format: "name CONTAINS[c] %#", searchController.searchBar.text)
If you need in more properties you do like this:
let searchPredicate = NSPredicate(format: "name CONTAINS[c] %# OR shortname CONTAINS[c] %#", searchController.searchBar.text, searchController.searchBar.text)
Can you post the definition of your Team object, and any sub-objects that it contains? (TeamData).
Also indicate where you expect the search text to appear in your team object.
I haven't used NSPRedicate a lot, but my understanding of the CONTAINS comparison is that it checks an individual field to see if it contains a substring. I don't think it will check all fields of the objects you're searching. That seems like what you're expecting.
let searchPredicate = NSPredicate(format: "name contains[c] %#", searchWord)
self.filteredArray = self.array.filteredArrayUsingPredicate(searchPredicate)

Resources