我有一些不友好的字典数组,这些字典又包含数据数组,我试图根据传递谓词的任何内部数组来过滤外部数组。我似乎无法创建NSPredicate来完成这项工作。我开始时:
NSPredicate *lookupPredicate = [NSPredicate predicateWithFormat:
@"row_values.property_id == %@ AND row_values.property_value == %@",
@"47cc67093475061e01000540", @"Male"];
[dataRows filterUsingPredicate:lookupPredicate];
这将不返回任何值。我尝试了各种形式的ANY,但似乎找不到能解析的任何内容。同样,目标是仅保留那些内部数组字典内容的谓词为true的外部数组字典。我可以看到我每天都在想办法解决这个问题,对此...之以鼻...有什么主意吗?
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.";
},
...
}
}
最佳答案
伙计,“不友好”在这个数组上是轻描淡写的!
好吧,我想我明白了:
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
“property”是一个字典数组。最后,将执行谓词,依次替换每个字典的
$rv
。在这种情况下,我们要查看字典是否具有特定的property_id
和特定的property_value
。如果是这样,它将被聚合到一个新的数组中,这就是将从SUBQUERY
返回的数组。换句话说,
SUBQUERY
将建立一个包含所有row_values的数组,这些数组具有我们想要的property_id
和property_value
。 最后,当我运行此代码时,我得到:
(
{
row = 1;
"row_values" = (
{
"property_id" = 47cc67093475061e01000542;
"property_value" = "Mr.";
},
{
"property_id" = 47cc67093475061e01000540;
"property_value" = Male;
}
);
}
)
关于iphone - NSPredicate子查询语法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9630237/