-
-
Save icodebuster/e935769ade3bcc766f09 to your computer and use it in GitHub Desktop.
How to do lots of cool things with NSArray. Inspired by NSHipster and WWDC 2013 Session 228 - "Hidden Gems in Cocoa and Cocoa Touch"
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
NSArray *albums = @[[Album albumWithName:@"Random Access Memories" price:9.99f], | |
[Album albumWithName:@"Clarity" price:6.99f], | |
[Album albumWithName:@"Weekend in America" price:7.99f], | |
[Album albumWithName:@"Weekend in America" price:7.90f], | |
[Album albumWithName:@"Bangarang EP" price:2.99f]]; | |
// Reversing an Array | |
__unused NSArray *reversed = albums.reverseObjectEnumerator.allObjects; | |
// PREDICATES | |
// Find by name | |
[[albums filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"name like %@", @"Bangarang EP"]].firstObject name]; | |
// Find by name case and diacritic insenstive | |
[[albums filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"name like[cd] %@", @"bangaráng ep"]].firstObject name]; | |
// Finding with *? | |
[[albums filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"name like[cd] %@", @"ba?garán*"]].firstObject name]; | |
// startswith, endswith | |
[[albums filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"name beginswith[cd] %@", @"bang"]].firstObject name]; | |
[[albums filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"name endswith[cd] %@", @"ies"]].firstObject name]; | |
// contains | |
[[albums filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"name contains[cd] %@", @"access"]].firstObject name]; | |
// Comparisons (chained up with object operator) | |
[[albums filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"price == %f", 9.99f]] valueForKeyPath:@"@unionOfObjects.name"]; | |
[[albums filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"price < %f", 9.99f]] valueForKeyPath:@"@unionOfObjects.name"]; | |
[[albums filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"price BETWEEN %@", @[@5, @9]]] valueForKeyPath:@"@unionOfObjects.name"]; | |
// Use %k to subtitute for key paths, because %@'s get wrapped with quotes | |
[[albums filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"%K like 'Clarity'", @"name" ]] valueForKeyPath:@"@unionOfObjects.name"]; | |
// and then there's blocks... easier to read? | |
[albums filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(Album *album, NSDictionary *bindings) { | |
return [album.name hasPrefix:@"Random"]; | |
}]]; | |
// Simple Collection Operators | |
// @count: Returns the number of objects in the collection as an NSNumber. | |
// @sum: Converts each object in the collection to a double, computes the sum, and returns the sum as an NSNumber. | |
// @avg: Takes the double value of each object in the collection, and returns the average value as an NSNumber. | |
// @max/@Min: Determines the maximum value using compare:. Objects must support comparison with one another for this to work. | |
NSArray *numArray = @[@1, @2, @3, @4, @5]; // NSNumbers are a little different than objects with properties, use .self | |
[numArray valueForKeyPath:@"@sum.self"]; | |
[numArray valueForKeyPath:@"@avg.self"]; | |
[numArray valueForKeyPath:@"@min.self"]; | |
[numArray valueForKeyPath:@"@max.self"]; | |
[numArray valueForKeyPath:@"@count.self"]; | |
[albums valueForKeyPath:@"@sum.price"]; | |
[albums valueForKeyPath:@"@avg.price"]; | |
[albums valueForKeyPath:@"@min.price"]; | |
[albums valueForKeyPath:@"@max.name"]; | |
// Object Operator | |
// @unionOfObjects / @distinctUnionOfObjects: Returns an array of the objects in the property specified in the key | |
// path to the right of the operator. @distinctUnionOfObjects removes duplicates, whereas @unionOfObjects does not. | |
// Important: This operator raises an exception if any of the leaf objects is nil. | |
[albums valueForKeyPath:@"@unionOfObjects.name"]; | |
[albums valueForKeyPath:@"@distinctUnionOfObjects.name"]; | |
NSArray *albums2 = @[[Album albumWithName:@"Random Access Memories" price:9.99f], | |
[Album albumWithName:@"Clarity" price:6.99f], | |
[Album albumWithName:@"Hear No Evil" price:7.90f], | |
[Album albumWithName:@"Hear No Evil" price:7.90f]]; | |
// @distinctUnionOfArrays / @unionOfArrays: Returns an array containing the combined values of each array in the collection, | |
// as specified by the key path to the right of the operator. As you'd expect, the distinct version removes duplicate values. | |
// @distinctUnionOfSets: Similar to @distinctUnionOfArrays, but it expects an NSSet containing NSSet objects, and returns an NSSet. | |
// Because sets can't contain duplicate values anyway, there is only the distinct operator. | |
[@[albums, albums2] valueForKeyPath:@"@unionOfArrays.name"]; | |
[@[albums, albums2] valueForKeyPath:@"@distinctUnionOfArrays.name"]; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment