How to search an NSSet or NSArray for an object which has an specific value for an specific property?

IphoneObjective CNsarrayNspredicateNsset

Iphone Problem Overview


How to search an NSSet or NSArray for an object which has an specific value for an specific property?

Example: I have an NSSet with 20 objects, and every object has an type property. I want to get the first object which has [theObject.type isEqualToString:@"standard"].

I remember that it was possible to use predicates somehow for this kind of stuff, right?

Iphone Solutions


Solution 1 - Iphone

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

NB: The notion of the first found object in an NSSet makes no sense since the order of the objects in a set is undefined.

Solution 2 - Iphone

You can get the filtered array as Jason and Ole have described, but since you just want one object, I'd use - indexOfObjectPassingTest: (if it's in an array) or -objectPassingTest: (if it's in a set) and avoid creating the second array.

Solution 3 - Iphone

Generally, I use indexOfObjectPassingTest: as I find it more convenient to express my test in Objective-C code rather than NSPredicate syntax. Here's a simple example (imagine that integerValue was actually a property):

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

The output of this code is:

hasTwo: YES (index was 2)
hasFour: NO (index was 2147483647)

Solution 4 - Iphone

NSArray* results = [theFullArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"SELF.type LIKE[cd] %@", @"standard"]];

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiondontWatchMyProfileView Question on Stackoverflow
Solution 1 - IphoneOle BegemannView Answer on Stackoverflow
Solution 2 - IphoneNSResponderView Answer on Stackoverflow
Solution 3 - IphoneCarl VeazeyView Answer on Stackoverflow
Solution 4 - IphoneJason CocoView Answer on Stackoverflow