Re: Predicate Help
Re: Predicate Help
- Subject: Re: Predicate Help
- From: Dave DeLong <email@hidden>
- Date: Wed, 12 Jan 2011 16:05:56 -0800
SUBQUERY! :)
NSArray *objects = ...; //your array of SRIndexObjects
NSPredicate * f = [NSPredicate predicateWithFormat:@"SUBQUERY(todos, $t, $t.todoCompletedDate >= %@).@count > 0", aParticularDate];
NSArray *filteredObjects = [objects filteredArrayUsingPredicate:f];
Explanation:
SUBQUERY() is kind of like a second level of filtering. The first parameter is a collection (or keypath to one, etc), the second parameter is a variable name (that iteratively represents each item in the collection), and the third parameter is a predicate.
So:
SUBQUERY(todos, $t, $t.todoCompletedDate >= %@)
This has the same effect as:
NSArray * filtered = [todos filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"todoCompletedDate >= %@", aParticularDate]];
Notice that it returns a collection, which means we can use the results in a larger expression. In this case, we're going to invoke the @count keyPath on it, which returns the number of items in the collection, which we'll compare against 0.
In a nutshell, that's a predicate that will find all objects in the source array that have at least one todo object, where that todo object's todoCompletedDate is on or after aParticularDate.
Sweet, huh?
Dave
On Jan 12, 2011, at 3:58 PM, Brad Stone wrote:
> I'm been trying for two days to get this to work. I've googled, read the "Predicate Programming Guide" - I guess I just don't get it.
>
> I'm trying to develop a predicate to populate a mutable array . I have an array that contains SRIndexObjects.
>
> @interface SRIndexObject : NSObject <NSCoding> {
> NSNumber *uid;
> NSArray * todos; // this is an array of SRIndexTodo objects
> }
>
> @interface SRIndexTodo : NSObject {
> NSDate * todoCompletedDate;
> }
>
>
>
> My goal is to find all the SRIndexObjects that have at least one todo where the completed date is greater than or equal to a particular date.
>
> this is the code:
>
> NSPredicate *hasTodosPredicate = [NSPredicate predicateWithFormat:@"todos[SIZE] > 0"]; // this works fine if I use this as the only predicate
> NSPredicate *compDatePredicate = [NSPredicate predicateWithFormat:@"ANY todos.todoCompletedDate >= %@", targetDate];
> NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:hasTodosPredicate, compDatePredicate, nil]];
>
> NSLog(@"%@", predicate);
> [currentFoundArray addObjectsFromArray:[tempArray filteredArrayUsingPredicate:predicate]]; // tempArray has 2000 SRIndexObjects, currentFoundArray is mutable and empty
>
> This is the result:
> 2011-01-12 18:43:43.090 testApp[37874:a0f] todos[SIZE] > 0 AND ANY todos.todoCompletedDate >= CAST(316328400.000000, "NSDate")
> 2011-01-12 18:44:24.957 testApp[37874:a0f] -[NSNull compare:]: unrecognized selector sent to instance 0xa036f6a0
>
> What I think is happening is since todos.todoCompletedDate can be nil it's causing the failure (the NSNull compare). I just don't know how to build a predicate to deal with that since I want to add the object to currentFoundArray if at least one is not nil and the date is >= targetDate.
>
> Help would be greatly appreciated.
>
> Thanks - Brad_______________________________________________
>
> Cocoa-dev mailing list (email@hidden)
>
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
>
> Help/Unsubscribe/Update your Subscription:
>
> This email sent to email@hidden
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden