2012-03-09 130 views
5

我有一种不友好的字典数组,它依次具有数据数组,我试图根据任何传递谓词的内部数组来过滤外部数组。我似乎无法创建一个NSPredicate来完成这项工作。我开始与:NSPredicate子查询语法

NSPredicate *lookupPredicate = [NSPredicate predicateWithFormat: 
      @"row_values.property_id == %@ AND row_values.property_value == %@", 
       @"47cc67093475061e01000540", @"Male"]; 

[dataRows filterUsingPredicate:lookupPredicate]; 

这将返回没有值。我尝试了各种形式的ANY,但我似乎无法找到任何它将解析的内容。同样,目标是仅保留那些内部数组字典内容的谓词为真的外部数组字典。我可以看到我咀嚼了一天的时间来弄清楚这个工作的咒语......任何想法?

dataRows: 
(
{ 
    row = 1; 
    "row_values" =  (
      { 
       "property_id" = 47cc67093475061e01000542; 
       "property_value" = "Mr."; 
      }, 
      { 
       "property_id" = 47cc67093475061e01000540; 
       "property_value" = Male; 
      } 
    ); 
}, 
{ 
    row = 2; 
    "row_values" =  (
      { 
      "property_id" = 47cc67093475061e01000542; 
      "property_value" = "Ms."; 
      }, 
... 
    } 
} 
+0

可能的重复[在哪里可以找到NSPredicate for Core Data的SUBQUERY功能的文档?](http://stackoverflow.com/questions/3076618/where-to-find-the-documentation-of-the- subquery-feature-of-nspredicate-for-core) – Senseful 2016-08-07 23:32:21

回答

21

男人,“不友好”是对该阵列的轻描淡写!

OK,我想我想通了这一点:

NSArray *dataRows = @[ 
         @{ @"row" : @"1", 
         @"row_values" : @[ 
              @{ @"property_id" : @"47cc67093475061e01000542", 
               @"property_value" : @"Mr." }, 
              @{ @"property_id" : @"47cc67093475061e01000540", 
               @"property_value" : @"Male" } 
              ] 
         }, 
         @{ @"row" : @"2", 
         @"row_values" : @[ 
              @{ @"property_id" : @"47cc67093475061e01000542", 
               @"property_value" : @"Ms." }, 
              @{ @"property_id" : @"47cc67093475061e01000540", 
               @"property_value" : @"Female" } 
              ] 
         } 
        ]; 

NSPredicate *p = [NSPredicate predicateWithFormat:@"SUBQUERY(row_values, $rv, $rv.property_id = %@ AND $rv.property_value = %@)[email protected] > 0", @"47cc67093475061e01000540", @"Male"]; 

NSArray *filtered = [dataRows filteredArrayUsingPredicate:p]; 

所以让我们看看这个谓词在做什么。

  1. 开始与最外面的电平:

    SUBQUERY([stuff])[email protected] > 0 
    

    SUBQUERY返回对象的数组。我们将在dataRows阵列中的每个NSDictionary上运行此SUBQUERY,并且我们想要聚合该字典上的SUBQUERY返回某些东西的所有字典。所以我们运行SUBQUERY,然后(因为它返回一个集合),询问它有多少项([email protected]),看看它是否大于0.如果是,那么顶级字典将在最终过滤数组。

  2. 挖到SUBQUERY

    SUBQUERY(row_values, $rv, $rv.property_id = %@ AND $rv.property_value = %@) 
    

    有三个参数,以每SUBQUERY:一个关键路径,变量,和谓词。关键路径是我们要迭代的对象的属性。由于SUBQUERY正在评估最外面的字典,我们将要求该字典的@"row_values"并取回数组。然后SUBQUERY将迭代row_values集合中的项目。

    变量是我们要调用集合中的每个项目的东西。在这种情况下,它只是$rv(“行值”的缩写)。在我们的例子中,每个$rv将是NSDictionary,因为row_values“属性”是一组字典。

    最后,谓词将被执行,依次为每个字典替换$rv。在这种情况下,我们想要查看字典是否有一定的property_id和某个property_value如果它确实是,它将被聚合成一个新的数组,,这就是将从SUBQUERY返回的数组。

    所以要说这是一种不同的方式,SUBQUERY将建立一个所有row_values数组,其中有我们正在寻找的property_idproperty_value

最后,当我运行此代码,我得到:

(
     { 
     row = 1; 
     "row_values" =   (
         { 
       "property_id" = 47cc67093475061e01000542; 
       "property_value" = "Mr."; 
      }, 
         { 
       "property_id" = 47cc67093475061e01000540; 
       "property_value" = Male; 
      } 
     ); 
    } 
) 
+1

其实我只是简化了源代码结构,所以我可以使用更简单的谓词。开玩笑......非常感谢你戴夫!这工作完美,它是有道理的。我非常感谢帮助,并告诉我如果您需要帮助,例如黑色的RGB值或英语中有多少元音 - 我可以处理的东西。 – michael 2012-03-09 17:09:57

+1

你真了不起,谢谢戴夫! – flypig 2012-11-22 10:53:58

0

苹果SUBQUERY文档分散在几个地方。描述的文档/语法SUBQUERY

为子查询表达式的字符串格式是:

SUBQUERY(collection_expression, variable_expression, predicate);

其中表达是一个谓词表达式,用于评估一个集合,variableExpression是一个将被用来包含每个个体的表达式集合的元素,谓词是用于确定元素是否属于结果集合的谓词。

有关更多详细信息和示例,请参阅my answer to a similar question about the documentation for SUBQUERY syntax