这里说我有一组具有两个属性的对象:
// array of object
NSArray *objects
// object
NSString *primaryTag;
NSArray *secondaryTag;
因为我想要的是当这个对象包含givenTag时,它可以被传递给一个名为results的新数组;
这是我的代码:
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:@"primaryTag == %@ || secondaryTag CONTAINS[c] %@", givenTag, givenTag];
results = [objects filteredArrayUsingPredicate:resultPredicate];
似乎primaryTag运行良好,但secondaryTag无法正常工作,有人可以帮助我。我对NSPredicate过滤并不熟悉。提前谢谢。
答案 0 :(得分:1)
最有效的方法是NSCompoundPredicate
如此:
NSArray *subPredicates = @[tag1, tag2, tag3];
NSPredicate *compoundPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:subPredicates];
你的问题有点不清楚所以你可能也想要:
andPredicateWithSubpredicates
具体取决于您要查找的结果集的性质。
请在此处查看Apple文档:NSCompoundPredicate Docs
答案 1 :(得分:1)
我实现了以下自定义类:
name
并覆盖它的NSLog语句的描述方法,以打印我们理解的内容:
@interface CustomObject : NSObject
@property (copy, nonatomic) NSString *primaryTag;
@property (strong, nonatomic) NSArray *secondaryTag;
@end
然后我从自定义类创建了一些对象并将它们添加到数组中:
- (NSString *)description {
return [NSString stringWithFormat:@"primaryTag: %@, secondaryTag: %@", _primaryTag, [_secondaryTag componentsJoinedByString:@", "]];
}
最后我创建了一个要搜索的字符串和谓词:
NSMutableArray *objects = [NSMutableArray array];
CustomObject *obj1 = [CustomObject new];
obj1.primaryTag = @"stringToSearchFor";
obj1.secondaryTag = @[@"notTheStringToSearchFor", @"somethingElse"];
[objects addObject:obj1];
CustomObject *obj2 = [CustomObject new];
obj2.primaryTag = @"differentString";
obj2.secondaryTag = @[@"nothingWeAreLookingFor"];
[objects addObject:obj2];
CustomObject *obj3 = [CustomObject new];
obj3.primaryTag = @"anotherOne";
obj3.secondaryTag = @[@"whoCaresForThisString", @"stringToSearchFor"];
[objects addObject:obj3];
当我退出结果时,我得到了正确的结果:
NSString *givenTag = @"stringToSearchFor";
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:@"primaryTag == %@ || secondaryTag CONTAINS[c] %@", givenTag, givenTag];
日志:
(适用 “primaryTag:stringToSearchFor,secondaryTag:notTheStringToSearchFor,somethingElse”, “primaryTag:anotherOne,secondaryTag:whoCaresForThisString,stringToSearchFor” )强>
是obj1和obj3。正确!如果它不适合你,你的代码就会出现其他问题......
答案 2 :(得分:0)
我看到了这个问题,
我的正常做法是两次使用NSPredicate,
这样我就可以在每个步骤跟踪结果: 选项1:
NSPredicate * resultPredicate1 = [NSPredicate predicateWithFormat:@“primaryTag ==%@”,givenTag]; results1 = [objects filteredArrayUsingPredicate:resultPredicate1];
NSPredicate * resultPredicate2 = [NSPredicate predicateWithFormat:@“secondaryTag CONTAINS [c]%@”,givenTag]; finalResults = [results1 filteredArrayUsingPredicate:resultPredicate2];
选项2: 使用NSCompoundPredicate复合多个过滤。您可以在google和stackOverFlow上轻松找到很多示例。
希望这会有所帮助, 谢谢
答案 3 :(得分:0)
如果我对原始问题的理解不正确,请告诉我,我会调整我的答案。
问题:您有一组具有2个属性的对象。一个是primaryTag
,这是一个字符串。第二个是secondaryTags
数组,它是一个字符串集合。您希望过滤primaryTag
匹配的所有对象,或者搜索字符串与secondaryTag
之一匹配的对象。
回答匹配字符串的正确方法是MATCHES
或CONTAINS
。
NSPredicate *pPredicate =
[NSPredicate predicateWithFormat:@"%K CONTAINS[cd] %@",
@"primaryTag", searchString];
NSPredicate *sPredicate =
[NSPredicate
predicateWithFormat:@"SUBQUERY(%K, $st, $st CONTAINS[cd] %@).@count > 0",
@"secondaryTags", searchString];
NSCompoundPredicate *searchPredicate =
[NSCompoundPredicate orPredicateWithSubPredicates:@[ pPredicate, sPredicate ]];
工作原理:第一个谓词是一个简单的匹配。您可以将CONTAINS
替换为MATCHES
,如果这更符合您希望的那种比较。 [cd]
后缀表示不区分大小写且对变音符号不敏感。在搜索/过滤时包含这些内容是正常的,但同样,它取决于您。我使用%K
和替换参数,而不是在谓词格式字符串中嵌入属性名称。在生产代码中,该替换参数将是常量。
第二个谓词有点棘手。它使用SUBQUERY()
来过滤secondaryTags
数组,并且如果至少一个辅助标记与搜索字符串匹配,则将对象返回为匹配。 SUBQUERY()
是一个包含3个参数的函数。第一个是被搜索的集合。第二个是临时变量,依次表示集合中的每个项目;它用在第3个参数中。第3个参数是常规谓词。集合中与筛选器匹配的每个项目都包含在SUBQUERY()
的输出中。最后,对匹配的辅助标记进行计数(通过@count
),如果计数大于零,则认为原始对象已匹配,因此将包含在已过滤的输出中。
最后,我们将这两个谓词组合成一个searchPredicate
,现在可用于过滤对象数组。