I have an NSArray
formed with objects of a custom class. The class has 3 (city, state, zip) string properties. I would like to get all unique state values from the array
.
I did read through the NSPredicate
class but couldn't make much of how to use it in this case. The only examples I could find were for string operations.
Can someone please help me out?
The main difference is that NSArray is for an ordered collection and NSSet is for an unordered collection. There are several articles out there that talk about the difference in speed between the two, like this one. If you're iterating through an unordered collection, NSSet is great.
arrays can't contain nil.
In Swift, the NSArray class conforms to the ArrayLiteralConvertible protocol, which allows it to be initialized with array literals. For more information about object literals in Swift, see Literal Expression in The Swift Programming Language (Swift 4.1).
NSSet is “toll-free bridged” with its Core Foundation counterpart, CFSet . See Toll-Free Bridging for more information on toll-free bridging. In Swift, use this class instead of a Set constant in cases where you require reference semantics.
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];
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With