我有一个具有多个属性的Core Data对象,其中一个属性称为Category。这是一个可以承担任何价值的字符串,我无法保证任何预先知识。我想运行一个fetch,它将返回一个Category值列表,这些值在Tag值与给定值匹配的所有存储元素之间共享。我不确定如何最好地描述这一点,所以这是一个例子:
ObjectNumber Tag Category
---------------------------------
01 AAA Red
02 AAA Green
03 AAA Blue
04 BBB Blue
05 BBB Red
06 BBB Yellow
07 CCC Blue
08 CCC Yellow
09 CCC Red
我希望我的fetch的结果是一个类别列表,这些类别在所有对象中共享,其Tag在集合{AAA,BBB,CCC}中,在这种情况下,将返回[" Red&# 34;," Blue"],因为这些是在标签位于给定集合中的任何对象之间共享的唯一类别。
我希望找到尽可能快的东西,因为当这个应用程序在真实项目上运行时,数据库中会有数万个对象。
答案 0 :(得分:2)
以下是我刚刚编写的代码示例,应该可以解决您的过滤问题。
在阅读文档和试验之后,我仍在学习NSFetchRequest和谓词的复杂性,虽然它并不复杂。
NSArray *setoftags = [NSArray arrayWithObjects: @"AAA", @"BBB", nil];
NSFetchRequest * request;
NSMutableSet *tagcategoriesset = nil;
for (NSString *tag in setoftags) {
request = [NSFetchRequest fetchRequestWithEntityName:@"ObjectWithCategories"];
NSPredicate *tagPredicate = [NSPredicate predicateWithFormat:@"%K == %@", @"Tag", tag];
request.predicate = tagPredicate;
NSArray *objects;
NSError *err;
NSMutableSet *tagcategories = [[NSMutableSet alloc] initWithCapacity:1];
if ( (objects = [self.managedObjectContext executeFetchRequest:request error:&err]) == nil) {
// error
NSLog(@"There was an error:\n%@", [err localizedDescription]);
}
else {
// fetch request succeeded
// Ignore any unused tags
if ( [objects count] == 0) continue;
// Collect the Category attribute into a mutable set
for(NSManagedObject *obj in objects) {
[tagcategories addObject: [(id)obj Category]];
}
// First assign, later intersect the tagcategories
if (tagcategoriesset == nil) {
tagcategoriesset = tagcategories;
}
else {
[tagcategoriesset intersectSet: tagcategories];
}
}
}
NSArray *finalCategories = [tagcategoriesset allObjects];
这是另一个SO Q& A供进一步讨论:using NSPredicate with a set of answers
答案 1 :(得分:1)
这些都是帮助我更好地理解NSPredicate
的好文章。我强烈推荐这些值得一读。
Using NSPredicate to Filter Data
这是简单NSPredicate
...
NSString *key = @"Category";
NSString *value = @"Red";
[NSPredicate predicateWithFormat:@"%K == %@", key, value]
这是一个更复杂的NSPredicate
...
NSString *key = @"Category";
NSString *value1 = @"Red";
NSString *value2 = @"Blue";
NSPredicate *predicateRed = [NSPredicate predicateWithFormat: @"%K == %@", key, value1];
NSPredicate *predicateBlue = [NSPredicate predicateWithFormat: @"%K == %@", key, value2];
NSPredicate *predicate = [NSCompoundPredicate orPredicateWithSubpredicates:@[predicateRed, predicateBlue]];
我使用这种格式来演示可以实现的目标。要清楚这第二个例子也可以更简单地写成......
NSPredicate *predicate = [NSPredicate predicateWithFormat: @"(%K == %@) || (%K == %@)", key, value1, key, value2];
这些示例并不是解决方案,但是用于演示帮助您开发解决方案的机制。
希望有所帮助。