Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSArray Equivalent of Map

Given an NSArray of NSDictionary objects (containing similar objects and keys) is it possible to write perform a map to an array of specified key? For example, in Ruby it can be done with:

array.map(&:name) 
like image 334
Stussa Avatar asked May 25 '11 16:05

Stussa


People also ask

What's a difference between NSArray and NSSet?

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.

What is difference between NSArray and NSMutableArray?

The primary difference between NSArray and NSMutableArray is that a mutable array can be changed/modified after it has been allocated and initialized, whereas an immutable array, NSArray , cannot.

What is an NSArray?

NSArray creates static arrays, and NSMutableArray creates dynamic arrays. You can use arrays when you need an ordered collection of objects. NSArray is “toll-free bridged” with its Core Foundation counterpart, CFArrayRef . See Toll-Free Bridging for more information on toll-free bridging.

What is difference between array and NSArray in Swift?

Array is a struct, therefore it is a value type in Swift. NSArray is an immutable Objective C class, therefore it is a reference type in Swift and it is bridged to Array<AnyObject> . NSMutableArray is the mutable subclass of NSArray . Because foo changes the local value of a and bar changes the reference.


2 Answers

It only saves a couple lines, but I use a category on NSArray. You need to ensure your block never returns nil, but other than that it's a time saver for cases where -[NSArray valueForKey:] won't work.

@interface NSArray (Map)  - (NSArray *)mapObjectsUsingBlock:(id (^)(id obj, NSUInteger idx))block;  @end  @implementation NSArray (Map)  - (NSArray *)mapObjectsUsingBlock:(id (^)(id obj, NSUInteger idx))block {     NSMutableArray *result = [NSMutableArray arrayWithCapacity:[self count]];     [self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {         [result addObject:block(obj, idx)];     }];     return result; }  @end 

Usage is much like -[NSArray enumerateObjectsWithBlock:]:

NSArray *people = @[                      @{ @"name": @"Bob", @"city": @"Boston" },                      @{ @"name": @"Rob", @"city": @"Cambridge" },                      @{ @"name": @"Robert", @"city": @"Somerville" }                   ]; // per the original question NSArray *names = [people mapObjectsUsingBlock:^(id obj, NSUInteger idx) {     return obj[@"name"]; }]; // (Bob, Rob, Robert)  // you can do just about anything in a block NSArray *fancyNames = [people mapObjectsUsingBlock:^(id obj, NSUInteger idx) {     return [NSString stringWithFormat:@"%@ of %@", obj[@"name"], obj[@"city"]]; }]; // (Bob of Boston, Rob of Cambridge, Robert of Somerville) 
like image 156
Justin Anderson Avatar answered Oct 08 '22 05:10

Justin Anderson


I've no idea what that bit of Ruby does but I think you are looking for NSArray's implementation of -valueForKey:. This sends -valueForKey: to every element of the array and returns an array of the results. If the elements in the receiving array are NSDictionaries, -valueForKey: is nearly the same as -objectForKey:. It will work as long as the key doesn't start with an @

like image 40
JeremyP Avatar answered Oct 08 '22 03:10

JeremyP