NSPredicate子查询语法

我有一个不友善的字典arrays,依次有数据的数组,我试图根据传递谓词的任何内部数组过滤外部数组。 我似乎无法创build一个NSPredicate来完成这个工作。 我开始与:

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

这不返回任何值。 我尝试了各种forms的任何forms,但我似乎无法find任何它将parsing。 同样,目标是只保留外部数组字典内的任何内部数组字典内容为真的谓词。 我可以看到我咀嚼了一天的时间,弄清楚这个工作的咒语……有什么想法?

 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."; }, ... } } 

男人,“不友善”是在这个arrays轻描淡写!

好的,我想我明白了这一点:

 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 = %@).@count > 0", @"47cc67093475061e01000540", @"Male"]; NSArray *filtered = [dataRows filteredArrayUsingPredicate:p]; 

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

  1. 从最外层开始:

     SUBQUERY([stuff]).@count > 0 

    SUBQUERY返回一个对象数组。 我们将在dataRows数组中的每个NSDictionary上运行这个SUBQUERY ,并且我们想要聚合该字典上的SUBQUERY返回的所有字典。 所以我们运行SUBQUERY ,然后(因为它返回一个集合),询问它有多less项( .@count ),看看它是否大于0.如果是,那么顶级字典将是在最后过滤的数组中。

  2. 挖掘到SUBQUERY

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

    每个SUBQUERY都有三个参数:一个关键path,一个variables和一个谓词。 关键path是我们要迭代的对象的属性。 由于SUBQUERY是在最外面的字典上进行评估的,我们将要求该字典的@"row_values"并返回一个数组。 SUBQUERY将遍历row_values集合中的项目。

    variables就是我们要调用集合中的每个项目。 在这种情况下,它仅仅是$rv (“row value”的缩写)。 在我们的例子中,每个$rv都是一个NSDictionary ,因为row_values “property”是一个字典数组。

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

    因此,要说一个不同的方式, SUBQUERY将构build一个所有row_value的数组,其中包含我们正在查找的property_idproperty_value

最后,当我运行这个代码时,我得到:

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

苹果的SUBQUERY文档分散在几个地方。

  • 描述SUBQUERY文档/语法的一个地方是在NSExpression(forSubquery:usingIteratorVariable:predicate :)文档中 :

子查询expression式的string格式是:

SUBQUERY(collection_expression, variable_expression, predicate);

其中expression是一个判断集合的谓词expression式,variableExpression是一个将被用来包含集合中每个单独元素的expression式,predicate是判断该元素是否属于结果集合的谓词。

有关更多详细信息和示例,请参阅我对有关SUBQUERY语法文档的类似问题的回答 。