An NSPredicate that can recursively traverse an object graph?
I'm trying to filter an array of objects that essentially form a tree-style graph. what i want to do is to filter out all objects from this array whose visible property is NO, or if its parent/grandparent/etc visible property is true (child objects can have the visible property be YES while its parent can be NO).
I'm unclear as to how i would go about this using NSPredicate syntax to keep searching the parent node until there are 开发者_开发百科no parents or the visible property is found. Is there any way to go about this?
Its been awhile since I asked this question, and I think I went in another direction with what i was doing, but there are some possibilities i realize now to solve what i wanted at the time:
- Have the visible property method behave recursively instead of making the format predicate do that. This could be accomplished like so:
- (BOOL) isVisible { return visible && [parent isVisible]; } //... id filtered = [array filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"visible == YES"]];
- Use block predicates instead of format predicates to do the recursive traversal:
[array filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) { id obj = evaluatedObject; while (obj) { if (![obj isVisible]) return NO; obj = [obj parent]; } return YES; }]];
Or a combination of the two (which would be the most robust and readable I think).
I'm not sure what you're looking to do is possible with a simple, single predicate. If it's a tree and you're using a predicate to get the nodes, you'd want and write a method that will traverse upwards and return a BOOL indicating whether it should be removed or not.
Then, just get your nodes and put them in an NSMutableArray and do a
for (int i = 0; i < [results count]; i++)
{
if ([self shouldBeRemoved:[results objectAtIndex:i]])
{
[results removeObjectAtIndex:i];
i--;
}
}
Your shouldBeRemoved: method should be pretty a straightforward recursive method.
精彩评论