iPhone - getting unique values from NSArray object
Take a look at keypaths. They are super powerful and I use them instead of NSPredicate classes most of the time. Here is how you would use them in your example...
NSArray *uniqueStates;
uniqueStates = [customObjects valueForKeyPath:@"@distinctUnionOfObjects.state"];
Note the use of valueForKeyPath instead of valueForKey.
Here is a more detailed/contrived example...
NSDictionary *arnold = [NSDictionary dictionaryWithObjectsAndKeys:@"arnold", @"name", @"california", @"state", nil];
NSDictionary *jimmy = [NSDictionary dictionaryWithObjectsAndKeys:@"jimmy", @"name", @"new york", @"state", nil];
NSDictionary *henry = [NSDictionary dictionaryWithObjectsAndKeys:@"henry", @"name", @"michigan", @"state", nil];
NSDictionary *woz = [NSDictionary dictionaryWithObjectsAndKeys:@"woz", @"name", @"california", @"state", nil];
NSArray *people = [NSArray arrayWithObjects:arnold, jimmy, henry, woz, nil];
NSLog(@"Unique States:\n %@", [people valueForKeyPath:@"@distinctUnionOfObjects.state"]);
// OUTPUT
// Unique States:
// "california",
// "michigan",
// "new york"
The totally simple one liner:
NSSet *uniqueStates = [NSSet setWithArray:[myArrayOfCustomObjects valueForKey:@"state"]];
The trick is the valueForKey:
method of NSArray
. That will iterate through your array (myArrayOfCustomObjects
), call the -state
method on each object, and build an array of the results. We then create an NSSet
with the resulting array of states to remove duplicates.
Starting with iOS 5 and OS X 10.7, there's a new class that can do this as well: NSOrderedSet
. The advantage of an ordered set is that it will remove any duplicates, but also maintain relative order.
NSArray *states = [myArrayOfCustomObjects valueForKey:@"state"];
NSOrderedSet *orderedSet = [NSOrderedSet orderedSetWithArray:states];
NSSet *uniqueStates = [orderedSet set];