我有一些不友好的字典数组,而这些字典又有数据数组,我试图根据传递谓词的任何内部数组来过滤外部数组。我似乎无法创建一个NSPredicate来使这项工作。我开始时:
NSPredicate *lookupPredicate = [NSPredicate predicateWithFormat:
@"row_values.property_id == %@ AND row_values.property_value == %@",
@"47cc67093475061e01000540", @"Male"];
[dataRows filterUsingPredicate:lookupPredicate];
这不返回任何值。我尝试了各种形式的任何形式,但我似乎找不到任何可以解析的东西。同样,目标是仅保留那些外部数组字典,其中内部数组字典内容的任何内容的谓词都为真。我可以看到我在弄清楚这个工作的咒语上花了一天时间...任何想法?
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 :(得分:21)
男人,“不友好”是对这个阵列的轻描淡写!
好吧,我想我想出来了:
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
返回一个对象数组。我们将在SUBQUERY
数组中的每个NSDictionary
上运行此dataRows
,并且我们希望聚合该字典上的SUBQUERY
返回的所有字典东西。所以我们运行SUBQUERY
,然后(因为它返回一个集合),询问它中有多少项(.@count
)并查看它是否大于0.如果是,那么顶级字典将位于最终过滤的数组中。
深入了解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
将构建一个包含我们正在寻找的property_id
和property_value
的所有row_values的数组。 / p>
最后,当我运行此代码时,我得到:
(
{
row = 1;
"row_values" = (
{
"property_id" = 47cc67093475061e01000542;
"property_value" = "Mr.";
},
{
"property_id" = 47cc67093475061e01000540;
"property_value" = Male;
}
);
}
)
答案 1 :(得分:0)
Apple的SUBQUERY文档分散在几个地方。
子查询表达式的字符串格式为:
SUBQUERY(collection_expression, variable_expression, predicate);
其中expression是一个计算集合的谓词表达式,variableExpression是一个表达式,用于包含集合的每个单独元素,而谓词是用于确定元素是否属于结果集合的谓词。
有关详细信息和示例,请参阅my answer to a similar question about the documentation for SUBQUERY syntax。