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];
那么让我们看看这个谓词在做什么。
-
从最外层开始:
SUBQUERY([stuff]).@count > 0
SUBQUERY
返回一个对象数组。 我们将在dataRows
数组中的每个NSDictionary
上运行这个SUBQUERY
,并且我们想要聚合该字典上的SUBQUERY
返回的所有字典。 所以我们运行SUBQUERY
,然后(因为它返回一个集合),询问它有多less项(.@count
),看看它是否大于0.如果是,那么顶级字典将是在最后过滤的数组中。 -
挖掘到
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_id
和property_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语法文档的类似问题的回答 。