Search code examples
objective-cnsarraynspredicate

NSPredicate to get a single attribute back from multiple objects in an array


This seems like it would be fairly simple to do, but I can't find anything referencing this specifically.

Say I have an array of Post objects that each have an objectId. How can I create an array of only the objectId's?

something like:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"objectId ALL"]; // I just want all the objectIds...
NSArray *results = [[self.objects filteredArrayUsingPredicate:predicate] mutableCopy];

or

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"objectId matches {anything}"];

Solution

  • NSPredicate cannot return anything other than BOOL, so it cannot return objectId. Moreover, filteredArrayUsingPredicate: can change the number of items in your array, but it will keep the objects themselves unchanged.

    If you want to start with one object and produce another object, you need NSExpression. It can transform your object into something else - for example, by projecting one of its attributes. However, Cocoa offers no built-in way of applying NSExpression to an NSArray in a way similar to filteredArrayUsingPredicate:, so NSExpression would not help here.

    You can solve this by using a little trick, though:

    NSString *key = NSStringFromSelector(@selector(objectId));
    NSMutableArray *allIds= [[array valueForKey:key] mutableCopy];
    

    If you use this in production code, it is a good idea to document it heavily by a few lines of comments. Otherwise, the readers of your code (including you in about six months or so) are virtually guaranteed to get confused.