基于下面的数据模型
根据用户输入,我创建一个名为 selectedTags 的实体Tag的managedObjects的NSSet。
[NSPredicate predicateWithFormat:@"ANY entryTags IN %@", selectedTags];
...这将返回任何条目,其中至少有一个entryTag集合中的entryTag。
我想要的是:
[NSPredicate predicateWithFormat:@"ALL entryTags IN %@", selectedTags];
...注意唯一的变化是“ANY”到“ALL”。这说明了我想要的,但不起作用。
制定我期望的结果:
我正在寻找一种解决方案,它只会返回条目标签,这些条目的所有标签都在selectedTags列表中(但同时,如果可能的话,不一定是相反的方式)。
进一步说明:
(标签)妈妈
(标签)爸爸
(标签)礼物
(条目)她是她.....(标签)妈妈
(参赛)他是他......(标签)爸爸
(入门)送给妈妈的礼物......(标签:)妈妈,礼物
(入门)给爸爸的礼物.....(标签:)爸爸,礼物
如果selectedTags包含“妈妈”和“礼物”,那么“爸爸的礼物”条目将会显示,因为它有“礼物”标签。我宁愿让它不显示:)
答案 0 :(得分:27)
到目前为止,这是明确的答案:
[NSPredicate predicateWithFormat:@"SUBQUERY(entryTags, $tag, $tag IN %@).@count = %d", selectedTags, [selectedTags count]];
B-E-A-U-T-I-F-U-L。
感谢Dave DeLong。
答案 1 :(得分:5)
使用复合谓词怎么样?据我所知,您希望返回所有与标签列表匹配的条目,而不仅仅是其中任何一个。一种方法是为每个标记创建一个谓词,然后使用复合谓词将它们组合在一起。
NSMutableArray *predicates = [[NSMutableArray alloc] init];
for (Tag *tag in selectedTags) {
[predicates addObject:[NSPredicate predicateWithFormat:@"ANY entryTags.tagName MATCHES %@", tag.tagName]];
}
NSPredicate *compoundPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:predicates];
这应该实现你想要的。然后根据您的请求设置此谓词。
答案 2 :(得分:4)
你不能用谓词做你想做的事。
ANY
和ALL
运算符适用于正在测试的实体(在本例中为Entry
),而不适用于集合的内容(selectedTags
)。任何一个运算符都将返回与该集合的任何单个元素匹配的Entry
对象。 ANY
运算符将返回它找到的第一个匹配项,而ALL
运算符将返回所有匹配项。在这两种情况下,它们都不会返回与所提供集合中的每个元素匹配的条目。
(看起来你也试图在Tag
中使用实际的selectedTags
个对象。这很可能不会起作用,因为没有专用比较方法的类上的对象比较通常会失败。它也很慢你需要比较谓词中的属性。)
由于您已经拥有所需的Tag
个对象,因此要查找与候选人相关的Entity
个对象,您只需要走Tag.taggedEntries
个关系。然后,您必须找到所有Entity
对象集的交集,才能找到与 每个 所选Entity
对象相关的Tag
个对象{{对象。由于没有交叉集合运算符,因此需要循环。
if ([selectedEntries count]>=2) {
NSMutableSet *intersectEntries=[[NSMutableSet alloc] initWithCapacity:1];
for (int i=1; i<[selectedTags count]; i++) {
if ([intersectEntries count]==0) {
[intersectEntries unionSet:[[selectedEntries objectAtIndex:(i-1)] valueForKey:@"taggedEntries"]];
}
[intersectEntries intersectSet:[[selectedEntries objectAtIndex:i] valueForKey:@"taggedEntries"]];
}
}
(注意:我没有对此进行测试,但它应该有效。)
现在intersectEntries
应该只包含与每个选定标记相关的Entry
个对象。
答案 3 :(得分:2)
我意识到我可以在这里回馈一些我之前得到的指导。通过使用TechZen提供的代码,我能够提出以下内容 - 对我来说非常有价值 - 代码片段:
- (NSArray *)unionSetOfObjectsForObjects:(NSArray *)objects {
NSMutableSet *unionSetOfObjects = [NSMutableSet set];
if (objects.count)
[unionSetOfObjects unionSet:[[objects objectAtIndex:0] valueForKey:@"key"]];
//unionSetOfObjects = [[objects objectAtIndex:0] valueForKey:@"key"];
if (objects.count > 1)
for (id object in objects)
[unionSetOfObjects intersectSet:[object valueForKey:@"key"]];
return unionSetOfObjects.allObjects;
}
如果此代码的作用不明显:
它收集key
数组中提供的所有对象上的键objects
的所有值(在我的案例中为对象)。
这段代码只是......味道不错,不是吗?
答案 4 :(得分:0)
最简单的方法:
[NSPredicate predicateWithFormat:@"entryTags IN %@", selectedTags];
您不需要ALL子句。它也在这里记录:
正如您在本文中所看到的,用户成功完成了这项工作(阅读原始问题的评论)