diff --git a/AWKHelpers.podspec b/AWKHelpers.podspec index b72d6f2..2c419bf 100644 --- a/AWKHelpers.podspec +++ b/AWKHelpers.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = "AWKHelpers" - s.version = "0.5" + s.version = "0.6" s.summary = "A growing collection of UIKit and Foundation categories (helpers)" s.description = <<-DESC A growing collection of UIKit and Foundation categories (helpers) we use at Awkward diff --git a/Classes/AWKArrayHelper.h b/Classes/AWKArrayHelper.h index dee4916..8aa7c04 100644 --- a/Classes/AWKArrayHelper.h +++ b/Classes/AWKArrayHelper.h @@ -8,6 +8,11 @@ #import +typedef NS_OPTIONS(NSUInteger, AWKArrayMappingOptions) { + AWKArrayMapNilToNull = 1<<0, + AWKArrayMapNilToDeletion = 1<<1 +}; + @interface NSArray (AWKArrayHelper) /** @@ -33,6 +38,16 @@ */ - (BOOL)hasObjectAtIndex:(NSUInteger)index; +/** + Creates a new array with new objects mapped to the values of the receicer array. The new values should be defined by the parameter block. + + @param mapBlock A block to return the destination values for the receiver array values. By default if you return nil, the new object will be copied from the receiver, unless you use a mapping option. + @param options Mapping options + + @return A newly created array with modified values based on the receiver array. + */ +- (NSArray *)arrayByMappingObjectsWithBlock:(id (^)(id obj, NSUInteger idx))mapBlock options:(AWKArrayMappingOptions)options; + @end @interface NSMutableArray (AWKArrayHelper) @@ -42,4 +57,13 @@ */ - (void)reverse; +/** + Replaces all objects of the array with other objects, returned by the given mapping block. + + @param mapBlock A block to return the new object to replace the old object in the array. By default, returning nil will result in an unchanged object, unless you use a mapping option. + @param options Mapping options + + */ +- (void)replaceObjectsWithBlock:(id (^)(id obj, NSUInteger idx))mapBlock options:(AWKArrayMappingOptions)options; + @end \ No newline at end of file diff --git a/Classes/AWKArrayHelper.m b/Classes/AWKArrayHelper.m index ed40f18..d8cdfc6 100644 --- a/Classes/AWKArrayHelper.m +++ b/Classes/AWKArrayHelper.m @@ -42,6 +42,23 @@ - (BOOL)hasObjectAtIndex:(NSUInteger)index { return YES; } +- (NSArray *)arrayByMappingObjectsWithBlock:(id (^)(id obj, NSUInteger idx))mapBlock options:(AWKArrayMappingOptions)options { + NSAssert(mapBlock!=nil, @"Map block should not be nil"); + NSMutableArray *mappedArray = [[NSMutableArray alloc] initWithCapacity:self.count]; + [self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + id result = mapBlock(obj, idx); + if (result) { + [mappedArray addObject:result]; + } else if (options&AWKArrayMapNilToNull) { + [mappedArray addObject:[NSNull null]]; + } else if ((options&AWKArrayMapNilToDeletion) == 0) { + [mappedArray addObject:obj]; + } + }]; + NSArray *resultArray = [mappedArray copy]; + return resultArray; +} + @end @implementation NSMutableArray (AWKArrayHelper) @@ -61,4 +78,23 @@ - (void)reverse { } } +- (void)replaceObjectsWithBlock:(id (^)(id obj, NSUInteger idx))mapBlock options:(AWKArrayMappingOptions)options{ + NSAssert(mapBlock!=nil, @"Map block should not be nil"); + NSMutableIndexSet *deletedIndices = [[NSMutableIndexSet alloc] init]; + for (NSUInteger idx = 0; idx < self.count; idx++) { + id oldObject = self[idx]; + id newObject = mapBlock(oldObject, idx); + if (newObject) { + [self replaceObjectAtIndex:idx withObject:newObject]; + } else if (options&AWKArrayMapNilToNull) { + [self replaceObjectAtIndex:idx withObject:[NSNull null]]; + } else if (options&AWKArrayMapNilToDeletion) { + [deletedIndices addIndex:idx]; + } + } + if (deletedIndices.count > 0) { + [self removeObjectsAtIndexes:deletedIndices]; + } +} + @end