Objective-C NSArray 高级运算符,map、flatmap、filter等

经常用swift的,会用到数组的一些高级运算符,比如map,flatmap,filter等,对数组的操作十分的友好,切换到swift时,通常会对NSArray的遍历,筛选等操作耽误功夫,因此想到把swift的操作符,在OC上进行改写。并增加结构联想,增加开发效率。

最终,希望实现的效果是这样子:

    NSArray<NSNumber *> * test = @[@1,@2,@3,@4,@5];
    
    //test map:<#^id _Nonnull(NSNumber * _Nonnull obj)transform#>
    NSArray<NSString *> *aftermap = [test map:^id _Nonnull(NSNumber * _Nonnull obj) {
        return [NSString stringWithFormat:@"%@", obj];
    }];
    NSArray<NSString *> *afterflatmap = [aftermap flatMap:^id _Nonnull(NSString * _Nonnull element) {
        return @[element, element, element];
    }];
    NSArray<NSString *> *afterfilter = [afterflatmap filter:^BOOL(NSString * _Nonnull obj) {
        return obj.integerValue > 3;
    }];
    NSArray<NSString *> *afterRemove = [afterfilter removeObjectsWhere:^BOOL(NSString * _Nonnull obj) {
        return obj.integerValue == 5;
    }];

//输出: aftermap:1,2,3,4,5
//输出: afterflatmap:1,1,1,2,2,2,3,3,3,4,4,4,5,5,5
//输出: afterfilter:4,4,4,5,5,5
//输出: afterRemove: 4,4,4

闲话不说,上代码

首先是NSArray+Monad.h文件

// 这里使用ObjectType的好处是,Xcode可以根据上文的类型,自动推断block中的类型,
// 减少编译时的误差,和自己转换格式的过程
@interface NSArray<ObjectType> (Monad)

- (NSArray*)map:(id(^)(ObjectType obj))transform;

- (NSArray<ObjectType>*)filter:(BOOL(^)(ObjectType obj))includeElement;

- (_Nullable ObjectType)first:(BOOL(^)(ObjectType obj))includeElement;

- (NSArray*)flatMap:(id (^)(ObjectType element))block;

- (NSInteger)firstIndexWhere:(BOOL(^)(ObjectType obj))includeElement;

- (NSArray<ObjectType>*)removeObjectsWhere:(BOOL(^)(ObjectType obj))includeElement;
@end

然后是实现文件。

@implementation NSArray (Monad)

- (NSArray*)map:(id(^)(id))transform {
    NSMutableArray *array = [[NSMutableArray alloc] init];
    for (id  _Nonnull obj in self) {
        [array addObject:transform(obj)];
    }
    return array;
    
}

- (NSArray*)filter:(BOOL(^)(id))includeElement {
    NSMutableArray *array = [[NSMutableArray alloc] init];
    
    [self enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if (includeElement(obj)) {
            [array addObject:obj];
        }
    }];
    
    return array;
}
- (NSArray*)removeObjectsWhere:(BOOL(^)(id))includeElement {
    NSMutableArray *array = [NSMutableArray arrayWithCapacity:0];
    for (id  _Nonnull obj in self) {
        if (!includeElement(obj)) {
            [array addObject:obj];
        }
    }
    return array;
}

- (NSArray *)flatMap:(id (^)(id element))block {
    NSMutableArray *result = [NSMutableArray array];
    for (id element in self) {
        id flatElement = block(element);
        if ([flatElement isKindOfClass:[NSArray class]]) {
            [result addObjectsFromArray:flatElement];
        } else if (flatElement){
            [result addObject:flatElement];
        } else {
            continue;
        }
    }
    return [result copy];
}
- (_Nullable id)first:(BOOL(^)(id obj))includeElement {
    for (id  _Nonnull obj in self) {
        if (includeElement(obj)) {
            return obj;
        }
    }
    return nil;
}
- (NSInteger)firstIndexWhere:(BOOL(^)(id obj))includeElement {
    for (int i = 0; i < self.count; i ++) {
        id ob = self[i];
        if (includeElement(ob)) {
            return i;
        }
    }
    return -1;
}
@end
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容