Error in search string in array - ios

This is my array :
<__NSArrayI 0x7ae43cd0>(
Regular,
Ultra
)
I'm searching in array in :
- (void)textFieldDidChange:(UITextField *)textField
{
NSPredicate *pred =[NSPredicate predicateWithFormat:#"name beginswith[c] %#", textField.text];
NSArray *filteredArr = [[[[arryService objectAtIndex:0] valueForKey:#"Category"] filteredArrayUsingPredicate:pred] mutableCopy];
NSLog(#"%#",filteredArr);
}
But it crash #
NSArray *filteredArr = [[[[arryService objectAtIndex:0] valueForKey:#"Category"] filteredArrayUsingPredicate:pred] mutableCopy];
Why it happens ?

Related

Search model using NSPredicate

Below is my model class
{"ID":1,"Name":"Area 1","Code":"xyz","StartTime":"09:30","EndTime":"13:40"},
{"ID":2,"Name":"Area 2","Code":"xyz","StartTime":"09:00","EndTime":"13:40"},
{"ID":3,"Name":"Area 3","Code":"xyz","StartTime":"10:30","EndTime":"14:40"},
{"ID":4,"Name":"Area 4","Code":null,"StartTime":"09:30","EndTime":"13:30"}]
I have retrieved model class value in NSMutableArray and displayed on TableView, Now I need to search name from model class, Below is my code, however its not been working.
-(void)updateSearchResultsForSearchController:(UISearchController *)searchController {
NSString *searchString = searchController.searchBar.text;
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF CONTAINS [cd] %#", searchString];
for (NSString *key in _arrAlreaList) {
NSArray *array = [_arrAlreaList valueForKey:key];
NSArray *tempArray = [array filteredArrayUsingPredicate:predicate];
if (tempArray.count > 0) {
[filteredArray addObjectsFromArray:tempArray];
[self.tblArea reloadData];
}
}
}
-(void)updateSearchResultsForSearchController:(UISearchController *)searchController {
NSString *searchString = searchController.searchBar.text;
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF.Name contains [c] %#", searchString];
NSArray *resultArray = [_arrAlreaList filteredArrayUsingPredicate:predicate];
NSLog(#"Result Array %#",resultArray);
}
Try This !!

NSPredicate for exact match

NSArray *arrData = [NSArray arrayWithObjects:
#"cloud,country,plant",
#"country,cloud,plant",
#"country,plant,cloud",
#"clouds,country,plant"
,#"country,clouds,plant",
nil];
From above NSArray, I want objects which having a word "cloud"
I tried below code
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"(self beginswith %# OR self contains[CD] %#)",#"cloud",#",cloud"];
NSArray *arrResult = [arrData filteredArrayUsingPredicate:predicate];
But it's giving all 5 objects in arrResult. But I need only 3 (0,1,2) objects.
Try:
NSPredicate* predicate = [NSPredicate predicateWithBlock:^(NSString* string, NSDictionary* options){
NSArray* array = [string componentsSeparatedByString:#","];
return [array containsObject:#"cloud"];
}];
Try below code,
It will work,
NSPredicate *hsPredicate = [NSPredicate predicateWithBlock:^BOOL(id _Nonnull evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) {
NSArray *sepretArray =[((NSString*)evaluatedObject) componentsSeparatedByString:#","];
NSPredicate *subPredicate = [NSPredicate predicateWithFormat:#"self == %#",#"cloud"];
return ([sepretArray filteredArrayUsingPredicate:subPredicate].count > 0);
}];
NSArray *arrResult = [arrData filteredArrayUsingPredicate:hsPredicate];
This one do the trick.But i don't know whether it is the efficient way of doing this.
NSArray *arrData = [NSArray arrayWithObjects:
#"cloud,country,plant",
#"country,cloud,plant",
#"country,plant,cloud",
#"clouds,country,plant"
,#"country,clouds,plant",
nil];
NSMutableArray *resArray = [[NSMutableArray alloc]init];
for(NSString *tempString in arrData)
{
NSArray *cache = [tempString componentsSeparatedByString:#","];
if([cache containsObject:#"cloud"])
{
[resArray addObject:tempString];
}
}

Faster way to iterate through a large NSArray of dictionaries

I created a "invite friends" feature for a iOS app I'm building. I was able to add alphabetical sections A-Z, by iterating through the large array, using NSPredicate picking out all names that start with A then B all the way to Z. Saving them into a dictionary were the keys are A-Z.
Everything works, but opening that view takes about 7 seconds from the moment I click the "invite friends" button.
What can I do to make this load seamlessly or atleast make it seem seamless to the users and improving the design and my code?
Here is my code
-(void)testing {
NSMutableArray *stringName = [[NSMutableArray alloc] init];
for (NSDictionary* item in self.tableData) {
// self.user = item;
NSString* firstName = [item objectForKey:#"firstName"];
[stringName addObject:firstName];
NSPredicate *aPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'A'"];
NSArray *beginWithA = [stringName filteredArrayUsingPredicate:aPredicate];
NSPredicate *bPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'B'"];
NSArray *beginWithB = [stringName filteredArrayUsingPredicate:bPredicate];
NSPredicate *cPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'C'"];
NSArray *beginWithC = [stringName filteredArrayUsingPredicate:cPredicate];
NSPredicate *dPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'D'"];
NSArray *beginWithD = [stringName filteredArrayUsingPredicate:dPredicate];
NSPredicate *ePredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'E'"];
NSArray *beginWithE = [stringName filteredArrayUsingPredicate:ePredicate];
NSPredicate *fPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'F'"];
NSArray *beginWithF = [stringName filteredArrayUsingPredicate:fPredicate];
NSPredicate *gPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'G'"];
NSArray *beginWithG = [stringName filteredArrayUsingPredicate:gPredicate];
NSPredicate *hPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'H'"];
NSArray *beginWithH = [stringName filteredArrayUsingPredicate:hPredicate];
NSPredicate *iPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'I'"];
NSArray *beginWithI = [stringName filteredArrayUsingPredicate:iPredicate];
NSPredicate *jPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'J'"];
NSArray *beginWithJ = [stringName filteredArrayUsingPredicate:jPredicate];
NSPredicate *kPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'K'"];
NSArray *beginWithK = [stringName filteredArrayUsingPredicate:kPredicate];
NSPredicate *lPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'L'"];
NSArray *beginWithL = [stringName filteredArrayUsingPredicate:lPredicate];
NSPredicate *mPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'M'"];
NSArray *beginWithM = [stringName filteredArrayUsingPredicate:mPredicate];
NSPredicate *nPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'N'"];
NSArray *beginWithN = [stringName filteredArrayUsingPredicate:nPredicate];
NSPredicate *oPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'O'"];
NSArray *beginWithO = [stringName filteredArrayUsingPredicate:oPredicate];
NSPredicate *pPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'P'"];
NSArray *beginWithP = [stringName filteredArrayUsingPredicate:pPredicate];
NSPredicate *qPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'Q'"];
NSArray *beginWithQ = [stringName filteredArrayUsingPredicate:qPredicate];
NSPredicate *rPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'R'"];
NSArray *beginWithR = [stringName filteredArrayUsingPredicate:rPredicate];
NSPredicate *sPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'S'"];
NSArray *beginWithS = [stringName filteredArrayUsingPredicate:sPredicate];
NSPredicate *tPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'T'"];
NSArray *beginWithT = [stringName filteredArrayUsingPredicate:tPredicate];
NSPredicate *uPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'U'"];
NSArray *beginWithU = [stringName filteredArrayUsingPredicate:uPredicate];
NSPredicate *vPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'V'"];
NSArray *beginWithV = [stringName filteredArrayUsingPredicate:vPredicate];
NSPredicate *wPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'W'"];
NSArray *beginWithW = [stringName filteredArrayUsingPredicate:wPredicate];
NSPredicate *xPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'X'"];
NSArray *beginWithX = [stringName filteredArrayUsingPredicate:xPredicate];
NSPredicate *yPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'Y'"];
NSArray *beginWithY = [stringName filteredArrayUsingPredicate:yPredicate];
NSPredicate *zPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'Z'"];
NSArray *beginWithZ = [stringName filteredArrayUsingPredicate:zPredicate];
// Dictionary
self.sectionDict = [[NSMutableDictionary alloc] init];
if (![beginWithA count] == 0) {
_sectionDict[#"A"] = beginWithA;
}
if (![beginWithB count] == 0) {
_sectionDict[#"B"] = beginWithB;
}
if (![beginWithC count] == 0) {
_sectionDict[#"C"] = beginWithC;
}
if (![beginWithD count] == 0) {
_sectionDict[#"D"] = beginWithD;
}
if (![beginWithE count] == 0) {
_sectionDict[#"E"] = beginWithE;
}
if (![beginWithF count] == 0) {
_sectionDict[#"F"] = beginWithF;
}
if (![beginWithG count] == 0) {
_sectionDict[#"G"] = beginWithG;
}
if (![beginWithH count] == 0) {
_sectionDict[#"H"] = beginWithH;
}
if (![beginWithI count] == 0) {
_sectionDict[#"I"] = beginWithI;
}
if (![beginWithJ count] == 0) {
_sectionDict[#"J"] = beginWithJ;
}
if (![beginWithK count] == 0) {
_sectionDict[#"K"] = beginWithK;
}
if (![beginWithL count] == 0) {
_sectionDict[#"L"] = beginWithL;
}
if (![beginWithM count] == 0) {
_sectionDict[#"M"] = beginWithM;
}
//
if (![beginWithN count] == 0) {
_sectionDict[#"N"] = beginWithN;
}
if (![beginWithO count] == 0) {
_sectionDict[#"O"] = beginWithO;
}
if (![beginWithP count] == 0) {
_sectionDict[#"P"] = beginWithP;
}
if (![beginWithQ count] == 0) {
_sectionDict[#"Q"] = beginWithQ;
}
if (![beginWithR count] == 0) {
_sectionDict[#"R"] = beginWithR;
}
if (![beginWithS count] == 0) {
_sectionDict[#"S"] = beginWithS;
}
if (![beginWithT count] == 0) {
_sectionDict[#"T"] = beginWithT;
}
if (![beginWithU count] == 0) {
_sectionDict[#"U"] = beginWithU;
}
if (![beginWithV count] == 0) {
_sectionDict[#"V"] = beginWithV;
}
if (![beginWithW count] == 0) {
_sectionDict[#"W"] = beginWithW;
}
if (![beginWithX count] == 0) {
_sectionDict[#"X"] = beginWithX;
}
if (![beginWithY count] == 0) {
_sectionDict[#"Y"] = beginWithY;
}
if (![beginWithZ count] == 0) {
_sectionDict[#"Z"] = beginWithZ;
}
}
self.dictSectionTitles = [[self.sectionDict allKeys] sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
}
Here is the other in which I call the method.
-(void)viewWillAppear:(BOOL)animated {
[self loadData];
}
- (void)loadData
{
[self.contactsManager importContacts:^(NSArray *contacts)
{
self.tableData = contacts;
[self testing];
[self.tableView reloadData];
NSLog(#"contacts: %#",contacts);
}];
}
Thanks!
You are essentially traversing the entire array 26 times. You need an algorithm that only traverses once, building up your dictionary as you go along.
NSMutableDictionary *sectionDict = [NSMutableDictionary dictionary];
for (NSString *s in array) {
NSString *firstLetter = [s substringToIndex:1];
NSMutableArray *section = sectionDict[firstLetter];
if (section == nil) {
section = [NSMutableArray array];
sectionDict[firstLetter] = section;
}
section addObject:s];
}

NSPredicate for multiple objects and properties

I have the following extension method to search in an array:
- (NSArray *)searchItemsForTerm:(NSString *)term;
{
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"name contains[c] %#", term];
return [[self filteredArrayUsingPredicate:resultPredicate] copy];
}
Sometimes not all my objects in the array have the "name" property. In this case I get an exception.
Is there a way to create this predicate which can ignore any non existing properties?
Thanks!
Something like:
- (NSArray *)searchItemsForTerm:(NSString *)term;
{
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"name contains[c] %#", term];
NSArray *filteredArray = [self filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
if ([evaluatedObject respondsToSelector:#selector(name)]) {
return [resultPredicate evaluateWithObject:evaluatedObject];
}
return NO;
}]];
return filteredArray;
}

Compare ValueForKey of an array with an NSString

I have an NSString which contains the folderName and i have an array which looks like this,
DATA (
{
FolderName = Posteingang;
ID = 13000;
},
{
FolderName = Freigaben;
ID = 13001;
},
{
FolderName = "My Drive";
ID = 13002;
},
{
FolderName = gsb;
ID = 13164;
},
{
FolderName = "my folder";
ID = 13183;
}
I would like to compare the array data with the NSString so i can remove the values from the string that do not match.
for (NSString *FileName in ParsedData)
{
NSRange FileNameRange = [FileName rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (FileNameRange.location == NSNotFound) {
[SearchData removeObject:[SearchData valueForKey:#"FolderName"]];
}
}
I have this Fast Enumeration method and i have the Array SearchData. The enumeration method looks for the data in the array and if that data is not found then it should remove it from the array.The SearchData array is to be displayed in a tableview.
I have been trying the above method but it doesn't work.
NSString *searchText = #"Posteingang";
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"FolderName = %#",searchText];
NSMutableArray *predarr = [NSMutableArray arrayWithArray:[yourDATAArray filteredArrayUsingPredicate:predicate]];
if([predarr count]!=0)
{
NSLog(#"%#",predarr);
}
Use this :
NSString *matchString = #"Posteingang";
for (int i = 0; i > [dataArray count]; i++) // Here dataArray is your array
{
NSMutableDictionary *allDict = [dataArray objectAtIndex:i];
if ([[allDict objectForKey:#"FolderName"] isEqualToString:matchString]) {
[dataArray removeObjectAtIndex:i];
}
}
hope it helps you.
NSString *stringToBeMatched = #"Freigaben";
for (NSDictionary *itemDic in array)
{
if ([[itemDic objectForKey:#"FolderName"] isEqualToString:stringToBeMatched])
{
[dataArray removeObject:itemDic];
}
}
After a little help from all the answers above i figured out the solution on my own
for (NSDictionary *dict in [SearchData copy]){
NSString *folderName = [dict objectForKey:#"FolderName"];
NSRange range= [folderName rangeOfString:searchText options:NSCaseInsensitiveSearch];
if(range.location == NSNotFound){
[SearchData removeObject:dict];
}
}
Try
NSArray *folders = #[#{#"FolderName":#"Posteingang",#"ID":#13000},
#{#"FolderName":#"Freigaben",#"ID":#13001},
#{#"FolderName":#"My Drive",#"ID":#13002},
#{#"FolderName":#"gsb",#"ID":#13164},
#{#"FolderName":#"my folder",#"ID":#13183}];
NSString *searchText = #"gsB";
//Choose a predicate that you want
//Case insensitive and diacritic search
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"FolderName LIKE [cd] %#",searchText];
//Case sensitive search
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"FolderName = %#",searchText];
//Any Matches
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"FolderName CONTAINS [cd] %#",searchText];
NSArray *filteredArray = [folders filteredArrayUsingPredicate:predicate];
EDIT : Filtering using fast enumeration
for (NSDictionary *dict in [SearchData copy]){
NSString *folderName = dict[#"FolderName"];
if([searchText localizedCaseInsensitiveCompare:folderName]){
[SearchData removeObject:dict];
}
}

Resources