开发者

An NSPredicate that can recursively traverse an object graph?

开发者 https://www.devze.com 2022-12-20 23:32 出处:网络
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/grandpa

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号