How to skip objects during iteration in ruby ​​like Map method for obj-c

Using the answer here , this method achieves something similar to a ruby ​​card in obj-c:

- (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; } 

My question is: how can I skip an object if something goes wrong while applying the block? Usually , to skip something in the enumerator, just use the return command, however this is not an option in the method above, since the block is expected to return something.

In this example, I use return to skip, but I get an error:

 NSArray *mappedArray = [objArray mapObjectsUsingBlock:^(id obj, NSUInteger i) { // i don't want this obj to be included in final array // so I try to skip it return; // ERROR:incompatible block pointer types sending // 'void(^)(__strong id, NSUInteger)' to parameter of type // 'id(^)(__strong id, NSUInteger)' // else do some processing return soupedUpObj; }]; 

My current way of working with it simply returns a null object, and then removes them from the final array. But I'm sure there should be a better way.

+2
ios objective-c iphone cocoa objective-c-blocks
Aug 21 '13 at 14:43
source share
3 answers

If the implementation is similar to what you showed above, it makes sense to simply apply the block result to an intermediate value, and then check it before adding it to the results array. Something like that:

 - (NSArray *)mapObjectsUsingBlock:(id (^)(id obj, NSUInteger idx))block { NSMutableArray *result = [NSMutableArray arrayWithCapacity:[self count]]; [self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { id blockResult = block( obj, idx ); if( result != nil ){ [result addObject:blockResult]; } }]; return result; } 
+4
Aug 21 '13 at 15:44
source share

One quick fix: write your own version that uses NSPointerArray, not NSArray. NSPointerArray can hold zero. Then the order can be saved, and you can use nil to indicate an error (assuming NSNull is a valid value that cannot be used to indicate an error). With NSPointerArray, your block will just return zero.

+1
Aug 21 '13 at 16:06 on
source share

This is simply a limitation of any mapObjectsUsingBlock: library framework or library mapObjectsUsingBlock: (this is not the standard Apple API).

Implementing the functionality of an array map is not difficult, so you can easily write your own version that processes nil return values ​​from a block argument.

0
Aug 21 '13 at 14:47
source share



All Articles