NSPredicate for custom objects not working - ios

I have array of custom objects, _momsArray. shown here is single object of such array:
Custom *yourMom {
name = #"Sally M. Brown";
age = 54;
weight = 43.2;
}
I run my predicate inside searchBar delegate:
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
if ([searchText length]<=0) {
_tableDataArr = [[NSMutableArray alloc] initWithArray:_momsArray];
} else{
// filtered _tableDataArr
NSString *filter = #"name BEGINSWITH[cd] %#";
NSPredicate* predicate = [NSPredicate predicateWithFormat:filter, searchText];
NSArray *filteredArr = [_momsArray filteredArrayUsingPredicate:predicate];
_tableDataArr = [[NSMutableArray alloc] initWithArray:filteredArr];
}
[_momTable reloadData];
}
This doesn't give expected result. For example, when I type S, sally doesn't appear at all. What is wrong with my code?
EDIT: The string in the custom objects contains punctuations and therefore it is not the same as other answers.

To filter an array with custom objects you can use this code.
NSString *str = #"text";
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"self.name contains[c] %#", str];
NSArray *arrFiltered = [self.arrDataObject filteredArrayUsingPredicate:predicate];
Hope, it helps.

Your string is not properly generated so use below code :
NSPredicate *predicate = [ NSPredicate predicateWithFormat:#"SELF beginswith[c] %#", text];
arrFilterData = [NSArray arrayWithArray:[arrDataList filteredArrayUsingPredicate:predicate]];
OUTPUT
Before search
After search
And with code
NSPredicate *predicate = [ NSPredicate predicateWithFormat:#"SELF CONTAINS[c] %#", text];
arrFilterData = [NSArray arrayWithArray:[arrDataList filteredArrayUsingPredicate:predicate]];
OutPut:
Edit
Output :

Use this code :
NSPredicate *pred = [NSPredicate predicateWithFormat:#"name CONTAINS[cd] %#", searchText];
NSMutableArray *filteredArr = [[_momsArray filteredArrayUsingPredicate:pred]mutableCopy];

Related

how to work with NSPredicate

I am try to search word which contain "EVBAR02". Can any body help me in this case. Here is Array Directory.
Here is code.
`NSMutableArray *filteredListContent = [NSMutableArray arrayWithArray:arrayGallery];
NSPredicate *predicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:#"imageUrl CONTAINS[cd] EVBAR02"];
[filteredListContent filterUsingPredicate:predicate];`
arrayGallery = (
{
imageId = "04";
imageUrl = "/article/THEV-EVBAR04.jpg";
},
{
imageId = "02";
imageUrl = "/article/THEV-EVBAR02.jpg";
},
{
imageId = "06";
imageUrl = "/article/THEV-EVBAR06.jpg";
}
)
But Its not working. What to do?
The ...WithFormat part of predicateWithFormat: works the same way like stringWithFormat:
NSString *searchString = #"EVBAR02";
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"imageUrl CONTAINS[cd] %#", searchString];
Or literally in single quotes:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"imageUrl CONTAINS[cd] 'EVBAR02'"];
The quotation is required as described in the documentation:
String constants must be quoted within the expression—single and
double quotes are both acceptable, but must be paired appropriately
(that is, a double quote (") does not match a single quote ('))
Vadian is right.
And if you want to pass the field name as a parameter, use %Kin place of %#:
NSString *searchField = #"imageUrl";
NSString *searchString = #"EVBAR02";
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"%K CONTAINS[cd] %#", searchField, searchString];
You have to set single quotes in your search string :
NSPredicate *predicate = [NSPredicate predicateWithFormat : #"imageUrl CONTAINS[cd] 'EVBAR02' "]
NSString *myString = #"EVBAR02";
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"imageUrl
contains[cd] %#", myString];
NSMutableArray *arrResult =[filteredListContent filteredArrayUsingPredicate:predicate];
There is no need of NSString stringWithFormat, directly use NSPredicate predicateWithFormat as below:
NSMutableArray *filteredListContent = [NSMutableArray arrayWithArray:arrayGallery];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"imageUrl CONTAINS[cd] 'EVBAR02'"];
[filteredListContent filterUsingPredicate:predicate];
Hope it will help:)

UISearchDisplayController with more than one search term

I wonder if there is any way to search for more than one word using UISearchDisplayController? If I for example want to search for posts containing both "James" AND "London"? Or "James" and "Smith"?
I have searched but not found an answer to this.
This is what I do now, to see if the search term is in either the name or address.
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
NSMutableArray *searchItemsPredicate = [NSMutableArray array];
NSPredicate *namePredicate = [NSPredicate predicateWithFormat:#"name contains[c] %#", searchText];
[searchItemsPredicate addObject:namePredicate];
NSPredicate *addressPredicate = [NSPredicate predicateWithFormat:#"address contains[c] %#", searchText];
[searchItemsPredicate addObject:addressPredicate];
NSCompoundPredicate *combinedPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:searchItemsPredicate];
searchResults = [_array filteredArrayUsingPredicate:combinedPredicate];
}
A possible solution would be to separate each words.
You can use a NSRegularExpression or use simply componentsSeparatedByString: (to keep it simple).
NSArray *words = [searchText componentsSeparatedByString:#" "];
NSMutableArray *allPredicates = [[NSMutableArray alloc] init];
for (NSString *aWord in words)
{
NSPredicate *addressPred = [NSPredicate predicateWithFormat:#"address contains[c] %#", aWord];
NSPredicate *namePred = [NSPredicate predicateWithFormat:#"name contains[c] %#", aWord];
[allPredicates addObject:addressPred];
[allPredicates addObject:namePred];
}
NSCompoundPredicate *finalPredicate = [[NSCompoundPredicate alloc] initWithType: NSOrPredicateType subPredicates:allPredicates];
searchResults = [_array filteredArrayUsingPredicate: finalPredicate];
You can use a more complexe scheme for your "words limitations" (comma, etc.) to mark delimitations for example:
Searching #"Banana, Apple fruit" could be in fact looking for "words" : #"Banana" and #"Apple fruit", in that case the separator string would be "," (and you may have to trim for white spaces).

Searching dictionary in array using predicate

I have an array of dictionaries and I want to find the dictionary with desired value for key "guid".
Can not get it with this code:
NSPredicate *filter = [NSPredicate predicateWithFormat:#"guid = %#", key];
NSArray *filteredContacts = [selectedValue filteredArrayUsingPredicate:filter];
Try this.
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"Name CONTAINS[cd] %#",searchBar.text];
filterdArray = [[hospitalArray filteredArrayUsingPredicate:predicate] mutableCopy];
Where Name is the key contained in the dictionary under the array.
I think you forgot "=" sign.
NSPredicate *filter = [NSPredicate predicateWithFormat:#"guid == %#", key];
NSArray *filteredContacts = [selectedValue filteredArrayUsingPredicate:filter];
The operator condition has been forgotten ;)
You need to add a double "=" like this :
NSPredicate *filter = [NSPredicate predicateWithFormat:#"guid == %#", key];
NSArray *filteredContacts = [selectedValue filteredArrayUsingPredicate:filter];
I hope this can help you !
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"(guid CONTAINS[c] %#)",key];
NSArray *array = [[NSArray arrayWithArray:sampleArray] filteredArrayUsingPredicate: predicate];
in above code "fromDate" is key of dictionary.
i hope this works for you.
Try this,
NSArray *filtered = [array_with_dict filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"(guid == %#)", #"desired value"]];
You could try to initiate the NSPredicate as:
NSPredicate *filter = [NSPredicate predicateWithFormat:[NSString stringWithFormat:#"guid = '%#'", key]];
Hope it helps.

How to create a predicate that compares all properties of an object?

For example, I have an object that has three properties: firstName, middleName, lastName.
If I want to search a string "john" in all the properties using NSPredicate.
Instead of creating a predicate like:
[NSPredicate predicateWithFormat:#"(firstName contains[cd] %#) OR (lastName contains[cd] %#) OR (middleName contains[cd] %#)", #"john", #"john", #"john"];
Can I do something like:
[NSPredicate predicateWithFormat:#"(all contains[cd] %#), #"john"];
"all contains" does not work in a predicate, and (as far as I know) there is no similar syntax to get the desired result.
The following code creates a "compound predicate" from all "String" attributes in the entity:
NSString *searchText = #"john";
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Entity" inManagedObjectContext:context];
NSMutableArray *subPredicates = [NSMutableArray array];
for (NSAttributeDescription *attr in [entity properties]) {
if ([attr isKindOfClass:[NSAttributeDescription class]]) {
if ([attr attributeType] == NSStringAttributeType) {
NSPredicate *tmp = [NSPredicate predicateWithFormat:#"%K CONTAINS[cd] %#", [attr name], searchText];
[subPredicates addObject:tmp];
}
}
}
NSPredicate *predicate = [NSCompoundPredicate orPredicateWithSubpredicates:subPredicates];
NSLog(#"%#", predicate);
// firstName CONTAINS[cd] "john" OR lastName CONTAINS[cd] "john" OR middleName CONTAINS[cd] "john"
You can do it in such way like,
NSMutableArray *allTheContaint = [[NSMutableArray alloc] init];
[allTheContaint addObject:allTheContaint.firstName];
[allTheContaint addObject:allTheContaint.middleName];
[allTheContaint addObject:allTheContaint.lastName];
NSPredicate *predicateProduct = [NSPredicate predicateWithFormat:#"SELF CONTAINS[cd] %#", #"john"];
NSArray *filteredArray = [self.listOfProducts filteredArrayUsingPredicate:predicateProduct];
NSLog(#"%#", filteredArray);
But it is fix. :( not for dynamic :)

NSPredicate to arrange NSMutableArray Objects?

I have multiple category list(around 45). i want to show some of the category to first like (Helicopter,Lake Monster,Dinosaur Attack) that will come at the starting after this remaning other will come. i have used the following code.
That works fine. But its to lengthy. so i want to filter this code.
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF IN %#", #[#"Helicopter", #"Lake Monster",#"Dinosaur Attack"]];
NSPredicate *predicate1 = [NSPredicate predicateWithFormat:#"packageName CONTAINS[cd] %#", #"Helicopter"];
NSPredicate *predicate2 = [NSPredicate predicateWithFormat:#"packageName CONTAINS[cd] %#", #"Lake Monster"];
NSPredicate *predicate3 = [NSPredicate predicateWithFormat:#"packageName CONTAINS[cd] %#", #"Dinosaur Attack"];
NSMutableArray *filteredArray = [[NSMutableArray alloc]init];
NSArray *arr1=[packages filteredArrayUsingPredicate:predicate1];
NSArray *arr2=[packages filteredArrayUsingPredicate:predicate2];
NSArray *arr3=[packages filteredArrayUsingPredicate:predicate3];
[filteredArray insertObject:[arr1 objectAtIndex:0] atIndex:0];
[filteredArray insertObject:[arr2 objectAtIndex:0] atIndex:1];
[filteredArray insertObject:[arr3 objectAtIndex:0] atIndex:2];
[packages removeObject:[arr1 objectAtIndex:0]];
[packages removeObject:[arr2 objectAtIndex:0]];
[packages removeObject:[arr3 objectAtIndex:0]];
So is there any way to achieve this result with shortest method?
Just cleaning up your own code, you could do the following:
NSPredicate *predicate1 = [NSPredicate predicateWithFormat:#"packageName CONTAINS[cd] %#", #"Helicopter"];
NSPredicate *predicate2 = [NSPredicate predicateWithFormat:#"packageName CONTAINS[cd] %#", #"Lake Monster"];
NSPredicate *predicate3 = [NSPredicate predicateWithFormat:#"packageName CONTAINS[cd] %#", #"Dinosaur Attack"];
NSMutableArray *filteredArray = [[NSMutableArray alloc]init];
for (NSPredicate *predicate in #[predicate1, predicate2, predicate3]) {
NSArray *arr=[packages filteredArrayUsingPredicate:predicate];
[filteredArray addObject:arr[0]];
[packages removeObject:arr[0]];
}
You should probably create a class (lets call it STOElement) that has two properties, (NSString*)text, and (NSNumber*)order. Create an instance of that class for each element 'Helicopter' etc, set that as the text, and then set the order you would like that element to appear in as the order (1,2,3 etc).
Then use the sortedArrayUsingComparator: to get an array with the order you want
NSArray* sortedArray = [arrayOfElements sortedArrayUsingComparator:^NSComparisonResult(STOElement* element1, STOElement* element2) {
return [element1.order compare:element2.order];
}];

Resources