53

如何在 NSSet 或 NSArray 中搜索具有特定属性的特定值的对象?

示例:我有一个包含 20 个对象的 NSSet,每个对象都有一个type属性。我想获得第一个具有[theObject.type isEqualToString:@"standard"].

我记得有可能以某种方式对这类东西使用谓词,对吧?

4

4 回答 4

80
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"type == %@", @"standard"];
NSArray *filteredArray = [myArray filteredArrayUsingPredicate:predicate];
id firstFoundObject = nil;
firstFoundObject =  filteredArray.count > 0 ? filteredArray.firstObject : nil;

注意:NSSet 中第一个找到对象的概念没有意义,因为集合中对象的顺序是未定义的。

于 2010-06-19T17:23:52.900 回答
17

您可以像 Jason 和 Ole 所描述的那样获得过滤后的数组,但由于您只想要一个对象,我会使用- indexOfObjectPassingTest:(如果它在一个数组中)或-objectPassingTest:(如果它在一个集合中)并避免创建第二个数组。

于 2010-06-20T21:19:06.660 回答
15

通常,我使用我发现用 Objective-C 代码而不是语法indexOfObjectPassingTest:来表达我的测试更方便。NSPredicate这是一个简单的例子(想象它integerValue实际上是一个属性):

NSArray *array = @[@0,@1,@2,@3];
NSUInteger indexOfTwo = [array indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
    return ([(NSNumber *)obj integerValue] == 2);
}];
NSUInteger indexOfFour = [array indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
    return ([(NSNumber *)obj integerValue] == 4);
}];
BOOL hasTwo = (indexOfTwo != NSNotFound);
BOOL hasFour = (indexOfFour != NSNotFound);
NSLog(@"hasTwo: %@ (index was %d)", hasTwo ? @"YES" : @"NO", indexOfTwo);
NSLog(@"hasFour: %@ (index was %d)", hasFour ? @"YES" : @"NO", indexOfFour);

这段代码的输出是:

hasTwo: YES (index was 2)
hasFour: NO (index was 2147483647)
于 2013-08-16T14:25:22.070 回答
4
NSArray* results = [theFullArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"SELF.type LIKE[cd] %@", @"standard"]];
于 2010-06-19T17:23:42.437 回答