Imagine you have the following structure for an NSArray of NSDictionary objects:
#define kFlameText #"text"
#define kFlameRelation #"relation"
NSArray* data = #[#{kFlameText:#"TextFlame1", kFlameRelation:#"Relation1"}, #{kFlameText:#"TextFlame2", kFlameRelation:#"Relation2"}, #{kFlameText:#"TextFlame3", kFlameRelation:#"Relation3"}}
You want to use a NSPredicate to extract the dictionary located in second position in your NSArray of NSDictionary based on the NSString #"Relation2"
You tried multiple times, with you last attempt being:
NSPredicate* sortFlames = [NSPredicate predicateWithFormat:#"SELF contains[cd] %#", #"Relation2"];
But you are still not there, you still get the following error message:
How would you make it work?
This predicate should do the trick:
NSPredicate *sortFlames = [NSPredicate predicateWithFormat:#"SELF.%K CONTAINS[cd] %#", kFlameRelation, #"Relation2"];
The %K is for the dynamic property name, more info here.
Related
I have a modelArr:
NSArray<MyModel *> *modelArr = xxx;
And in the MyModel, has property, such as type.
How can I filter the modelArr to get a new Array only have the same type?
You can use NSPredicate for that.
Compare type property with specific value.
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"type = %#", searchType];
NSArray *filterArray = [modelArr filteredArrayUsingPredicate:predicate];
If you want to check type property contains specific value than
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"type contains[cd] %#", searchType];
NSArray *filterArray = [modelArr filteredArrayUsingPredicate:predicate];
You can use NSPredicate, Please use this code
NSPredicate *bPredicate = [NSPredicate predicateWithFormat:#"SELF.name contains[cd] %#",self.searchText.text];
self.filteredArray = [self.hotelArray filteredArrayUsingPredicate:bPredicate];
NSLog(#"HERE %#",self.filteredArray);`
Try this
NSArray *uniqueNames = [modelArr valueForKeyPath:#"#distinctUnionOfObjects.type"];
Is it possible to use nspredicate to compare whether one NSArray is exactly equal to another NSArray of strings? I need this dome via predicates because of its possible I will add this predicate to a compound predicate.
The Array I am comparing against is a property of an NSDictionary.
So the answer was a mixture of both, I did use the predicatewithformat but got creative in the string inside, inspired by #akashivskyy and #avi
[predicatesArray addObject:[NSPredicate predicateWithFormat:#"ANY dynamic.values == %#", arr]];
Edit: As (partially) suggested by Avi, you may use the equality predicate:
NSArray *otherArray = #[ #"foo", #"bar" ];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"self == %#", otherArray];
[predicate evaluateWithObject:#[ #"foo", #"bar" ]]; // YES
[predicate evaluateWithObject:#[ #"baz", #"qux" ]]; // NO
Alternatively, and if you have any trouble with format string in the future, you may always use a block predicate to perform your own logic:
NSArray *otherArray = #[ #"foo", #"bar" ];
NSPredicate *predicate = [NSPredicate predicateWithBlock:^(NSArray *evaluatedArray, NSDictionary<NSString *, id> *bindings) {
return [evaluatedArray isEqualToArray:otherArray];
}];
// use the predicate
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 would like to filter an NSArray of NSDictionaries, however I would like to filter the result using one, two or even three NSPredicate values?
Currently I am filtering my array by doing this.
NSPredicate *predicateString = [NSPredicate predicateWithFormat:#"parts == %#", filterString];//keySelected is NSString itself
NSMutableArray *filteredArray = [NSMutableArray arrayWithArray:[currentParts filteredArrayUsingPredicate:predicateString]];
sortedItemsArray = [filteredArray mutableCopy];
But I am not sure how I would do this using two predicates?
The other two predicates individually look like the one above accept different keys.
NSPredicate *predicateString = [NSPredicate predicateWithFormat:#"area == %#", filterString];
and
NSPredicate *predicateString = [NSPredicate predicateWithFormat:#"item == %#", filterString];
What I was thinking is that maybe you could have something like
NSPredicate *predicateString = [NSPredicate predicateWithFormat:#"stage == %# area == %#", filterString, areaflterstring];
But I don't think that's possible.
It is possible, but you need to tell the predicate how to combine the parts, like:
NSPredicate *predicateString = [NSPredicate predicateWithFormat:#"stage == %# AND area == %#", filterString, areaflterstring];
You can alternatively use NSCompoundPredicate to combine a number of predicates.
I would like to figure out the NSPredicate that will search my Core data for words that begins with:
For example:
description field in the core data has text like this:
My name is Mike
My name is Moe
My name is Peter
My name is George
If I search 'My name is' I need to get the 3 lines
If I search 'My name is M' I need to get the first 2 lines
I tried the code below, but can't get what I need. My guess I need a regular expression, but not sure how to do it.
[NSPredicate predicateWithFormat:#"desc beginswith [cd] %#",word];
I did it this way recently and worked fine. Try it out. I see I don't have [cd] and beginswith but contains. You could give it a try.
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF contains %#", textField.text];
NSArray *list = [allWords filteredArrayUsingPredicate:predicate];
for(NSString *word in list){
NSLog(#"%#",word);
}
After reading the comments on the starting post:
First of all, you should split up the words in the string from the textfield:
NSArray *myWords = [textField.text componentsSeparatedByString:#" "];
Then doing the same like you first would:
for(NSString *wordFromTextField in myWords){
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF contains %#", wordFromTextField];
NSArray *list = [allWords filteredArrayUsingPredicate:predicate];
for(NSString *word in list){
NSLog(#"%#",word);
}
}
Instead of NSLogging the words you could add them to an array of course.