Accessing Custom objects within custom objects in an NSPredicate - iphone

I have a mutable array of custom Contact objects who in turn have Address objects.
I want to filter that array by attribute of the object, for example contact.address.pincode using
[myContacts filterUsingPredicate:myPredicate];
So I create a predicate like this :
[NSPredicate predicateWithFormat:#"Address.pincode BEGINSWITH[cd] %# OR Address.pincode CONTAINS[cd] %#",searchText,[NSString stringWithFormat:#" %#",searchText]];
which obviously does not work.
My question is how access Contact.Address.pincode inside the predicate format string?
Thanks

Related

how can i use predicateWithFormat for two different Class

i need to imlement search with to different class ons is Song and the other one is Album. etch one of them is represent song/album with his property (name,url,etc..).
now i am using this code to search song from my songArray by searching the name property, i need to also be able to search in the albumArray, also in the name property.
-(void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope {
// Update the filtered array based on the search text and scope.
// Remove all objects from the filtered search array
[self.filteredSongArray removeAllObjects];
// Filter the array using NSPredicate
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF._songName contains[cd] %#",searchText];
filteredSongArray = [NSMutableArray arrayWithArray:[_myDataMgr.songArray filteredArrayUsingPredicate:predicate]];
}
so my qustion is how can i tell the the predicate to look also in the AlbumArray
thank you all.
UPDATE:
i ran another predicate on the AlbumArray and after i got the results i added the two arrays. thank your replay was very helpful!
You can filter the array contents like this:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"(songName CONTAINS[cd] %#)", searchText];
[self.filteredSongArray addObjectsFromArray [_myDataMgr.songArray filteredArrayUsingPredicate:predicate]];
No need to add SELF in predicate....
Hope this helps...!!!

NSArray filteredArrayUsingPredicate: contains in other NSArray with custom key path

I have 2 NSArrays with each containing custom objects:
NSArrayToFilter
NSArrayUsedForFiltering
I want to filter my first array with a predicate that uses my second array. I want to return all the custom objects from my NSArrayToFilter where an attribute is not available in an other attribute from the custom objects in my NSArrayUsedForFiltering.
This is some pseudo-code for what I want to achieve:
[NSArrayToFilter filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"NOT self.attribute IN %#.attribute", NSArrayUsedForFiltering]

Core Data with multiple to Many Predicates

For a relationship like this:
TagGroups<---->>Tags<<---->>Object
An Object has tags, tags can be grouped by tagGroups.
I have an object, and I want to know all of the TagGroups its Tags belong to.
To construct he predicate, I first tried the following format string:
(SELF is a TagGroup)
NSPredicate* p = [NSPredicate predicateWithFormat:#"%# IN SELF.tags.objects" , object];
This fails because sets are not traversed ala Key-ValueCoding.
After some research I have found several questions explaining SUBQUERY
Core Data, try to use NSPredicate to filter a toMany relationship set but get the "to-many key not allowed here" error
Core data to-many NSPredicate with AND
These seem to be part of the solution, but unlike these questions I am not testing for a value like "tag.name", but membership within the collection.
So with that in mind I tried this:
NSPredicate* p = [NSPredicate predicateWithFormat:#"%# IN SUBQUERY(SELF.tags, $eachTag,$eachTag.object)" , object];
Which fails to parse (I tried a few other variants unsuccessfully as well)
Any ideas on how to construct this format string properly?
Update:
Also tried it from the other direction:
NSPredicate* p = [NSPredicate predicateWithFormat:#"ALL SUBQUERY(%#.tags,$eachTag,$eachTag.tagGroup)" , anObject];
If you "have an object" i.e. you have a particular managedObject whose entity is Object then you don't need a predicate. You just need to walk the relationship keypath.
Here is an example implemented with dictionaries by it works the same way with a managed object.
NSDictionary *tagGroup1=[NSDictionary dictionaryWithObjectsAndKeys:#"tagGroupOne",#"name",#"tagGroup1",#"theValue",nil];
NSDictionary *tagGroup2=[NSDictionary dictionaryWithObjectsAndKeys:#"tagGroupTwo",#"name",#"tagGroup2",#"theValue",nil];
NSDictionary *tag1=[NSDictionary dictionaryWithObject:tagGroup1 forKey:#"tagGroup"];
NSDictionary *tag2=[NSDictionary dictionaryWithObject:tagGroup2 forKey:#"tagGroup"];
NSSet *tags=[NSSet setWithObjects:tag1,tag2,nil];
NSDictionary *objD=[NSDictionary dictionaryWithObjectsAndKeys:tags,#"tags",nil];
NSLog(#"tagGroup names=%#",[objD valueForKeyPath:#"tags.tagGroup.name"]);
NSLog(#"tagGroup objects=%#",[objD valueForKeyPath:#"tags.tagGroup"]);
... which outputs:
tagGroup names={(
tagGroupTwo,
tagGroupOne
)}
tagGroup objects={(
{
name = tagGroupTwo;
theValue = tagGroup2;
},
{
name = tagGroupOne;
theValue = tagGroup1;
}
)}
So, really all you need is a line like:
NSSet *tagGroups=[anInstanceOfObject valueForKeyPath:#"tags.tagGroup"];
That's the power of key-value coding.
You would only need a subquery if you were trying to fetch Objects that had a relationship to a TagGroup with a particular attribute value.

NSPredicate for fetching keywords that are in a string

In core data I have an entity called keyword with a property 'text'. I want to find all keyword objects that are contained in a particular sting.
I tried:
[NSPredicate predicateWithFormat:#"%# contains[c] text", myString];
But that crashes. It seems like if it will only work if it's reversed.
The predicate works on the entity, so you have your predicate reversed. Since your entity's text property contains a single word, you'd split the string into multiple words and then test:
// This is very simple and only meant to illustrate the property, you should
// use a proper regex to divide your string and you should probably then fold
// and denormalize the components, etc.
NSSet* wordsInString = [NSSet setWithArray:[myString componentsSeparatedByString:#" "]];
NSPredicate* pred = [NSPredicate predicateWithFormat:#"SELF.text IN %#", wordsInString];
I think you're doing in reverse direction.
Try this.
[NSPredicate predicateWithFormat:#"text contains[cd] %#", myString];

Filtering against properties of objects in an array with a predicate

I have an array of objects that I'd like to filter using a predicate, but I've not been able to figure out the syntax (or whether it's impossible).
Let's say the object is location and it has properties of latitude and longitude. I've got an array of these called allLocations and I want to produce a new array of locations where the latitude property is greater than 30.
When fetching managed objects you can simply use the property name, but not so with arrays:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"latitude > 30.0"];
returns no matches (despite there being plenty of location objects with latitudes > 30.0.
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF.latitude > 30.0"];
is no good either, while
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"[SELF latitude] > 30.0"];
and
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"[location latitude] > 30.0"];
throw exceptions.
Am I out of luck?
What you're looking for is the filteredArrayUsingPredicate: method of NSArray. Your first predicate attempt above will work fine when you pass it to that method.
It's worth noting that NSMutableArray uses a different method to achieve a similar effect, filterUsingPredicate:. The MutableArray version alters the receiver, whereas the Array version returns a new Array.
Reference:
NSArray Class Reference
NSMutableArray Class Reference