Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
@interface MappedArraySentinel : NSObject @end
@implementation MappedArraySentinel @end
@interface LazyMappedArray ()
@property (nonatomic) NSArray *originalArray;
@property (nonatomic) NSMutableArray *backingArray;
@property (nonatomic, copy) id (^block)(id);
@implementation LazyMappedArray
- (instancetype)initWithArray:(NSArray *)array transformationBlock:(id (^)(id object))block {
self = [super init];
if (!self) return nil;
_originalArray = array;
_block = [block copy];
return self;
- (NSMutableArray *)backingArray {
if (!_backingArray) {
NSMutableArray *mappedArray = [NSMutableArray arrayWithCapacity:self.originalArray.count];
for (NSInteger i = 0; i < self.originalArray.count; i++) {
[mappedArray addObject:[MappedArraySentinel new]];
self.backingArray = mappedArray;
return _backingArray;
- (NSUInteger)count {
return self.backingArray.count;
- (id)objectAtIndex:(NSUInteger)index {
if ([[self.backingArray objectAtIndex:index] isKindOfClass:[MappedArraySentinel class]]) {
[self.backingArray replaceObjectAtIndex:index withObject:self.block(self.originalArray[index]) ?: [NSNull null]];
return [self.backingArray objectAtIndex:index];

This comment has been minimized.

Copy link

@honood honood commented Oct 29, 2015

Is there a bug? If customs call - initWithArray:transformationBlock: with an array of type NSMutableArray, and modify that array immediately, later call methods on LazyMappedArray object, he may get unexpected result.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment