代码之家  ›  专栏  ›  技术社区  ›  Kevlar

可以递归地遍历对象图的nspredicate?

  •  3
  • Kevlar  · 技术社区  · 14 年前

    我试图过滤一组基本上形成树型图的对象。我要做的是从这个数组中筛选出可见属性为“否”的所有对象,或者如果它的父/祖父母/等可见属性为“真”(子对象的可见属性可以为“是”,而父对象的可见属性可以为“否”)。

    我不清楚如何使用nspredicate语法继续搜索父节点,直到找不到父节点或可见属性为止。有什么办法可以解决这个问题吗?

    2 回复  |  直到 12 年前
        1
  •  1
  •   Kevlar    12 年前

    我问这个问题已经有一段时间了,我想我所做的是朝另一个方向发展,但现在我意识到有一些可能性可以解决我当时想要的问题:

    • 让Visible属性方法以递归方式工作,而不是让格式谓词这样做。 可以这样完成:
    - (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;
    }]];
    

    或者两者的结合(我认为这是最健壮和可读的)。

        2
  •  0
  •   Ash Furrow    14 年前

    我不确定用一个简单的单谓词可以做什么。如果它是一棵树,并且您使用谓词来获取节点,那么您需要并编写一个方法,该方法将向上遍历并返回一个bool,指示是否应该删除它。

    然后,把你的节点放到一个非可变数组中,做一个

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

    您的shouldberemoved:方法应该是非常简单的递归方法。