I'm trying to write a filter with NSPredicate that states:
IF field_Uid contains 47 and field_Target contains 202...display these items
This portion works great. However, I also want to show items in which the reverse is true, eg.:
OR IF fieldUid contains 202 and fieldTarget contains 47...display these
items also
Right now, I have the following code:
NSString *targetedUser = #"47";
NSString *myID = #"202";
NSPredicate *p1 = [NSPredicate predicateWithFormat:#"fieldUid contains[cd] %#", targetedUser];
NSPredicate *p2 = [NSPredicate predicateWithFormat:#"fieldTarget contains[cd] %#", myID];
//E.G. See p3 & p4 being the reverse?
// NSPredicate *p3 = [NSPredicate predicateWithFormat:#"fieldUid contains[cd] %#", myID];
// NSPredicate *p4 = [NSPredicate predicateWithFormat:#"fieldTarget contains[cd] %#", targetedUser];
NSCompoundPredicate *p = [NSCompoundPredicate andPredicateWithSubpredicates:#[p1, p2/*, p3, p4*/]];
NSArray *filtered = [self.messages filteredArrayUsingPredicate:p];
How would I write in the latter? I'm not sure how to do it without making the statement requiring all 4 lines to be true? (See commented out code - I've left it in so you can see what I mean...)
Just combine two compound "and" predicates using a compound "or" predicate.
You have the first compound "and" predicate in your question. Create the 2nd compound "and" predicate as needed.
Now use [NSCompoundPredicate orPredicateWithSubpredicates:] passing in the two "and" compound predicates.
you can also use
NSString *targetedUser = #"47";
NSString *myID = #"202";
//this will easily fix your issue, simply update your query like this
NSPredicate *p = [NSPredicate predicateWithFormat:#"(fieldUid contains[cd] %# AND fieldTarget contains[cd] %#) OR (fieldUid contains[cd] %# AND fieldTarget contains[cd] %#)", targetedUser, myID, myID, targetedUser];
NSArray *filtered = [self.messages filteredArrayUsingPredicate:p];
Related
I have built an NSPredicate similar to that below before and it worked perfectly. However, this time, it is generating the error:
'NSRangeException', reason: '-[NSTaggedPointerString characterAtIndex:]: Index 1 out of bounds; string length 1'
Here is how I build the predicate:
NSString *shortTitleClause = nil;
NSString *longTitleClause = nil;
Edit:
Adding clauses:
shortTitleClause =[NSString stringWithFormat:#"(shorttitle contains[c] %#)", searchText];
longTitleClause =[NSString stringWithFormat:#"(longtitle contains[c] %#)", searchText];
//My actual predicate has many more clauses but am getting same error no matter how many.
NSMutableArray *predArr = [#[] mutableCopy];
if (shortTitleClause.length > 0){
[predArr addObject:shortTitleClause];
}
if (longTitleClause.length > 0){
[predArr addObject:longTitleClause];
}
NSString *predStr = [predArr componentsJoinedByString:#"||"];
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:predStr];
searchResults = [theBooks filteredArrayUsingPredicate:resultPredicate];
When searching for the letter 'S' the predicate logs as: `(shorttitle contains[c] S)||(longtitle contains[c] S)`
It is not clear to me what the taggedPointerString refers to me. Can anyone see why I am getting this error?
You cannot use stringWithFormat to replace %# values when preparing predicates. Use predicateWithFormat instead. And don't join them using componentsJoinedByString - use NSCompoundPredicate to combine multiple predicates:
shortTitlePredicate = [NSPredicate predicateWithFormat:#"(shorttitle contains[c] %#)", searchText];
longTitlePredicate = [NSPredicate predicateWithFormat:#"(longtitle contains[c] %#)", searchText];
NSPredicate *resultPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:#[shortTitlePredicate,longTitlePredicate]];
For example, I have object like #{#"firstName":#"aaa", #"lastName":#"bbb"}.
Now I'm trying to search with next predicate:
NSPredicate *predicateFirstName = [NSPredicate predicateWithFormat:#"firstName contains [c] %#", searchString];
NSPredicate *predicateLastName = [NSPredicate predicateWithFormat:#"lastName contains [c] %#", searchString];
NSPredicate *orPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:#[predicateFirstName, predicateLastName]];
searchUsersArray = [usersArray filteredArrayUsingPredicate:orPredicate];
I need a predicate, which will be return for search string #"aa bb" users whose first name ENDED with "aa" and lastName BEGINS with #"bb"
NSPredicate *predicateLastName = [NSPredicate predicateWithFormat:#"(firstName AND lastName contains [c] %#)", searchString]
don't work for me.
First divide the search string in the end-part and the begin-part:
NSArray *parts = [#"aa bb" componentsSeperatedByString:#" "];
Then use BEGINSWITH and ENDSWITH:
[NSPredicate predicateWithFormat:#"(firstName ENDSWITH[c] %#) AND (lastName BEGINSWITH[c] %#", parts[0], parts[1]];
Alternatively you can add a computed property to the entity concatinating the first name and last name and then search in this property.
Try like this hope it help you
NSString *matchString = [NSString stringWithFormat: #"(.*aa|bb.*)",searchText];
NSString *predicateString = #"keyword MATCHES[c] %#";
NSPredicate *predicate =[NSPredicate predicateWithFormat: predicateString, matchString];
Thanks
Use keyword BEGINSWITH instead of contains.
NSPredicate *predicateFirstName = [NSPredicate predicateWithFormat:#"firstName BEGINSWITH [c] %#", searchString];
NSPredicate *predicateLastName = [NSPredicate predicateWithFormat:#"lastName BEGINSWITH [c] %#", searchString];
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:)
I would like to know how if at all to use a compound NSPredicate?
I have made an attempt as follows however the currentInstall array is exactly the same at the start as it is after the predicate has been applied.
NSArray *currentInstall = [coreDataController filterReadInstalls:selectedInstallID];
NSArray *tempArray = [currentInstalls filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"cHR == 0"]];
currentInstalls = [tempArray copy];
NSPredicate *predicateAreaString = [NSPredicate predicateWithFormat:#"area == %#", [myFilter objectForKey:#"area"]];
NSPredicate *predicateBString = [NSPredicate predicateWithFormat:#"stage == %#", [myFilter objectForKey:#"area2"]];
NSPredicate *predicateCString = [NSPredicate predicateWithFormat:#"partCode == %#", [myFilter objectForKey:#"area3"]];
NSPredicate *predicateDString = [NSPredicate predicateWithFormat:#"doorNo CONTAINS[cd] %#", [myFilter objectForKey:#"door"]];
NSPredicate *predicateEString = [NSPredicate predicateWithFormat:#"doorDesc CONTAINS[cd] %#", [myFilter objectForKey:#"doorDesc"]];
NSPredicate *compoundPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:#[predicateAreaString, predicateBString, predicateCString, predicateDString, predicateEString]];
NSMutableArray *filteredArray = [NSMutableArray arrayWithArray:[currentInstalls filteredArrayUsingPredicate:compoundPredicate]];
currentInstalls = [filteredArray mutableCopy];
There doesn't seem to be anything obviously wrong with the way you have implemented NSCompundPredicate. If you are not trying to And or Not predicates then I would say it is something wrong with your predicate formats and how they match the array you are filtering.
I would try to use just 2 of the predicates to create an NSCompundPredicate then get that working or see what is causing your issue. NSHipster also has some good info about NSPredicates.
i'm trying to filter a string array with this predicate:
[NSPredicate predicateWithFormat:#"SELF LIKE[c] '#*!%d'", aNumber]
Every string which is like #WILDCARD!ANY_NUMBER is valid.
But it doesn't work :(
Can you help me?
EDIT:
NSString *pattern = [#"#*!" stringByAppendingFormat:#"%d", numberVariable];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", pattern];
NSArray *filteredArray = [anArray filteredArrayUsingPredicate:pred];
The array anArray contains Strings like #0!-1 (numberVariable is -1) but the array filterdArray is empty. So the regex doesn't work.
EDIT:
My Solution:
NSString *pattern = [#"#.*!\\" stringByAppendingFormat:#"%d", numberVariable];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", pattern];
NSArray *filteredArray = [anArray filteredArrayUsingPredicate:pred];
To find all strings that look like "#ANY_CHARACTERS!ANY_NUMBER" with an arbitrary number, you need the "MATCHES" operator with a regular expression:
NSPredicate *pred = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", #"#.*!\\d+"];
NSArray *filtered = [yourArray filteredArrayUsingPredicate:pred];
If you have a specific number aNumber and want to find all strings of the form
"#ANY_CHARACTERS!<aNumber>", then the following should work:
NSString *pattern = [#"#*!" stringByAppendingFormat:#"%d", aNumber];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"SELF LIKE %#", pattern];
NSArray *filtered = [yourArray filteredArrayUsingPredicate:pred];
The problem with your
[NSPredicate predicateWithFormat:#"SELF LIKE[c] '#*!%d'", aNumber]
is that %d inside quotation marks is not replaced by aNumber.