我有以下结构:
TxnSummary * t1 = [[TxnSummary alloc] init];
t1.txnId = @"1";
t1.shortDesc = @"First one";
t1.filters = [[NSArray alloc] initWithObjects:@"F1", @"F2", nil];
TxnSummary * t2 = [[TxnSummary alloc] init];
t2.txnId = @"2";
t2.shortDesc = @"Second one";
t2.filters = [[NSArray alloc] initWithObjects:@"F1",@"F2", @"F3", nil];
TxnSummary * t3 = [[TxnSummary alloc] init];
t3.txnId = @"3";
t3.shortDesc = @"Third one";
t3.filters = [[NSArray alloc] initWithObjects:@"F1", @"F3", nil];
TxnSummary * t4 = [[TxnSummary alloc] init];
t4.txnId = @"4";
t4.shortDesc = @"Fourth one";
t4.filters = [[NSArray alloc] initWithObjects:@"F4", nil];
NSArray * xnArray = [[NSArray alloc] initWithObjects:t1,t2,t3,t4, nil];
现在,如果我想找出哪些txn摘要有过滤器F1,那么我可以这样做:
NSPredicate * predicate = [NSPredicate predicateWithFormat:@"filters CONTAINS[cd] %@", @"F1"];
NSArray * filteredArray = [xnArray filteredArrayUsingPredicate:predicate];
如果我只比较一个字符串,这很有效,但是如果想知道哪些txn摘要都有过滤器“F1”或“F2”,那么如果我必须按照上述机制我会有创建两个谓词 - 每个谓词用于F1和F2,然后针对xnArray运行它(这看起来效率很低)。我希望能够创建一个过滤器字符串列表,并使用它来从xn数组中获取匹配的tx。
NSArray * filterStrings = [[NSArray alloc] initWithObjects:@"F1",@"F2", nil];
NSPredicate是否具有实现此目的的功能,还是应该使用其他一些过滤方法?
感谢您的帮助。
谢谢Kumar
答案 0 :(得分:4)
如果我理解正确,您可以通过从谓词数组创建复合谓词来实现此目的,例如:
NSPredicate *newFilterPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:selectedItemIDs];
编辑:添加了更详细的解释:
复合谓词将谓词组合成一个谓词。例如,如果要筛选包含“F1”或“F2”的项目,请执行以下操作:
// Normally build this in some kind of loop
NSPredicate *firstPredicate = [NSPredicate predicateWithFormat:@"filter =%@", @"F1"];
NSPredicate *secondPredicate = [NSPredicate predicateWithFormat:@"filter =%@", @"F1"];
// Create the array of predicates
NSArray *arrayOfPredicates = [NSArray arrayWithObjects:firstPredicate, secondPredicate, nil];
// Create the compound predicate
NSPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:arrayOfPredicates];
还有“and”而不是“or”以及其他布尔条件的方法。完整的参考资料可以在这里找到:NSCompoundPredicate Class Reference
希望这有帮助,
戴夫
答案 1 :(得分:3)
您可以执行以下操作:
NSPredicate * predicate = [NSPredicate predicateWithFormat:@"filters CONTAINS[cd] %@ || filters CONTAINS[cd] %@", @"F1", @"F4"];
如果要添加数组中的所有键,可以执行以下操作:
NSArray * filterStrings = [[NSArray alloc] initWithObjects:@"F1",@"F4", nil];
NSString* predicateString = [filterStrings componentsJoinedByString:@"'|| filters CONTAINS[cd] '"];
predicateString = [NSString stringWithFormat:@"filters CONTAINS[cd] '%@'",predicateString];
NSPredicate * predicate = [NSPredicate predicateWithFormat:predicateString];
NSArray * filteredArray = [xnArray filteredArrayUsingPredicate:predicate];
答案 2 :(得分:1)
我不会使用NSArray来存储过滤器。这是使用NSSet/NSMutableSet代替的完美书籍示例。您可以与数组类似地进行初始化:
t1.filters = [[NSSet alloc] initWithObjects:@"F1", @"F2", nil];
然后,只需调用:
即可检查特定字符串是否存在BOOL contains = [t1.filter containsObject:@"F1"];
您现在还可以使用filteredSetUsingPredicate
,objectsPassingTest
等方法过滤该集合(与块一起使用),甚至可以与其他集合创建交叉点或联合(isSubsetOfSet
,{{1}等等)。因此,例如,您可以使用搜索的元素创建一个新集合,并检查集合是否包含它们:
intersectsSet
搜索集合比数组快得多,因为set由Hash table备份,而数组必须线性搜索。
答案 3 :(得分:0)
如果完全匹配是正确的,您可以使用IN
谓词,如下所示:
NSArray *filterStrings = [NSArray arrayWithObjects:@"F1", @"F2", nil];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"filters IN %@", filterStrings];
NSArray *filteredArray = [xnArray filteredArrayUsingPredicate:predicate];