2010-02-18 4 views
3

Я пытаюсь отфильтровать массив объектов, которые по существу образуют граф в стиле дерева. то, что я хочу сделать, - это отфильтровать все объекты из этого массива, чье видимое свойство НЕТ, или его истинное свойство родительского/grandparent/etc (дочерние объекты могут иметь видимое свойство YES, а его родительский элемент может быть NO).NSPredicate, который может рекурсивно пересекать граф объектов?

Непонятно, как я буду использовать это, используя синтаксис NSPredicate, чтобы продолжать поиск родительского узла до тех пор, пока не будут найдены родители или обнаружено свойство visible. Есть ли способ сделать это?

ответ

1

Ее было некоторое время, так как я задал этот вопрос, и я думаю, что я пошел в другом направлении с тем, что я делаю, но есть некоторые возможности я понимаю теперь, чтобы решить, что я хотел в то время:

  • Пусть метод видимого свойства ведет себя рекурсивно, а не делает предикат формата. Это может быть достигнуто следующим образом:
- (BOOL) isVisible { 
    return visible && [parent isVisible]; 
} 

//... 
id filtered = [array filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"visible == YES"]]; 
  • Используйте блок предикаты вместо формата предикаты сделать рекурсивный обход:
[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 сочетание два (которые были бы наиболее надежными и читаемыми, я думаю).

0

Я не уверен, что вы хотите сделать, это возможно с помощью простого одиночного предиката. Если это дерево и вы используете предикат для получения узлов, вам нужно и написать метод, который будет проходить вверх и вернуть BOOL, указывающий, следует ли его удалить или нет.

Тогда просто получить свои узлы и поместить их в NSMutableArray и сделать

for (int i = 0; i < [results count]; i++) 
{ 
    if ([self shouldBeRemoved:[results objectAtIndex:i]]) 
    { 
     [results removeObjectAtIndex:i]; 
     i--; 
    } 
} 

Ваш shouldBeRemoved: метод должен быть довольно простой рекурсивный метод.

 Смежные вопросы

  • Нет связанных вопросов^_^