2012-03-22 78 views
1
数组

我有以下结构:比较与其他使用NSPredicate

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数组中获取匹配的txs。

NSArray * filterStrings = [[NSArray alloc] initWithObjects:@"F1",@"F2", nil]; 

NSPredicate是否具有实现这一功能的功能,还是应该使用其他方法进行过滤?

感谢您的帮助。

感谢,库马尔

回答

3

你可以做这样的事情

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]; 
+0

完美。感谢您的输入。 – KumarM 2012-03-27 13:21:56

0

如果精确匹配OK,你可以使用IN谓词像这样:

NSArray *filterStrings = [NSArray arrayWithObjects:@"F1", @"F2", nil]; 
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"filters IN %@", filterStrings]; 

NSArray *filteredArray = [xnArray filteredArrayUsingPredicate:predicate]; 
+0

这是一个或匹配。例如,xn 1可以包含过滤器字符串F1,F2,而xn 2可以包含F2,F3,假设我想要找出所有具有过滤器字符串F1或F3的xns,则xn 1和xn 2都匹配。 – KumarM 2012-03-22 12:58:36

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]; 

也有对的“和”,而不是“或”以及其他布尔条件的方法。完整的参考可以在这里找到:NSCompoundPredicate Class Reference

希望这有助于

戴夫

+0

你能否详细说明一下? – KumarM 2012-03-22 12:57:23

+0

当然会增加更多我的回答 – 2012-03-22 13:25:58

+0

感谢您的解释。帮助学习有关谓词的新事物。我试过这个,它的功能就像一个魅力。你认为比下面ggrana提供的解决方案更有效吗? – KumarM 2012-03-27 13:25:20

1

我不会用NSArray中存储的过滤器。这是使用NSSet/NSMutableSet代替的完美书本式示例。您同样可以初始化数组:

t1.filters = [[NSSet alloc] initWithObjects:@"F1", @"F2", nil]; 

然后你检查是否是特定字符串存在就是通过调用:

BOOL contains = [t1.filter containsObject:@"F1"]; 

现在您还可以过滤设定与像filteredSetUsingPredicate方法,objectsPassingTest(使用与块),甚至创建交集或与其他集联合(isSubsetOfSet,intersectsSet等)。因此,例如,你可以创建一个新的集合与搜索到的内容,并检查组包含他们:

NSSet* toFind = [[NSSet alloc] initWithObjects:@"F1", @"F3", nil]; 
[toFind isSubsetOfSet:t1.filters]; 

搜索一组是不是一个数组,因为一组由Hash table备份更快,而一个数组线性搜索。如果您要添加的所有是一个数组中的键,你可以做这样的事情

NSPredicate * predicate = [NSPredicate predicateWithFormat:@"filters CONTAINS[cd] %@ || filters CONTAINS[cd] %@", @"F1", @"F4"];