NSPredicate and NSArray - ios

Is there a way to setup a NSPredicate that will search for all items in an NSArray?
something like:
NSPredicate *predicate = [NSPredicate predicateWithFormat: #"group.name == %#", arrayOfNames];

Use "IN" instead of "==" if the right-hand side is an array or set:
[NSPredicate predicateWithFormat: #"group.name IN %#", arrayOfNames]

Yes you can use NSPredicate with NSArray like this
NSArray *data = [NSArray arrayWithObject:[NSMutableDictionary dictionaryWithObject:#"foo" forKey:#"BAR"]];
NSArray *filtered = [data filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"(BAR == %#)", #"foo"]];

Related

Inverse of values using NSPredicate IOS

NSArray *arrValues = [NSArray arrayWithObjects:#"ABCD",#"ABCE",#"CDE"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF CONTAINS[cd]%#",#"ABC"];
NSArray *arrFiltered = [arrValues filteredArrayUsingPredicate:predicate];
I am aware that arrFiltered will contain the result ABCD and ABCE.
But, I want the result as CDE.
Is there a way to find the inverse of the predicate specified. ie., !(ABC)
Try to use NOT with predicate
NSArray *arrValues = [NSArray arrayWithObjects:#"ABCD",#"ABCE",#"CDE"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"NOT (SELF CONTAINS[cd] %#"),#"ABC"];
NSArray *arrFiltered = [arrValues filteredArrayUsingPredicate:predicate];
try
[NSPredicate predicateWithFormat:#"SELF !=[c] %#",#"ABC"];
The [c] makes the equality comparison case-insensitive.
Option-2
NSArray *arrValues = [NSArray arrayWithObjects:#"ABCD",#"ABCE",#"CDE",nil];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"NOT (SELF CONTAINS %#)",#"ABC"];
NSArray *arrFiltered = [arrValues filteredArrayUsingPredicate:predicate];
you get output as

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 use a compound NSPredicate?

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.

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

NSPredicate search LIKE

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.

Resources