美文网首页
Block 实现高阶函数(map filter)

Block 实现高阶函数(map filter)

作者: ikonan | 来源:发表于2018-08-31 13:01 被阅读22次

在swift中提供了包括map、filter、reduce等十分简洁优秀的高阶函数供我们对数组数据进行操作,同样情况下,遍历一个数组并求和在使用oc(不使用kvc)和swift的环境下的代码是这样的:

#pragma mark - OC code
NSArray numbers = @[@10, @15, @99, @66, @25];
NSInteger totalNumber = 0;
for (NSNumber number in numbers) {
    totalNumber += number.integerValue;
}

#pragma mark - swift code
let numbers = [10, 15, 99, 66, 25];
let totalNumber = numbers.reduce(0, { $0+$1 })

无论是代码量还是简洁性,此时的oc都比不上swift。那么接下来就要通过神奇的block来为oc添加这些高阶函数的实现。为此我们需要新建一个NSArray的分类扩展,命名为 NSArray+HigherFunc

NSArray+HigherFunc.h 内容如下:

#import <Foundation/Foundation.h>

//数组元素转换
typedef id(^HigherFuncItemMap)(id item);
typedef NSArray*(^HigherFuncArrayMap)(HigherFuncItemMap itemMap);

//数组元素筛选
typedef BOOL(^HigherFuncItemFilter)(id item);
typedef NSArray*(^HigherFuncArrayFilter)(HigherFuncItemFilter itemFilter);

@interface NSArray (HigherFunc)
@property (nonatomic, copy, readonly) HigherFuncArrayMap map;
@property (nonatomic, copy, readonly) HigherFuncArrayFilter filter;

@end

实现链式编程,函数调用的前提是具有返回对象。因此我使用了typedef声明了几个不同类型的block。虽然本质上HigherFuncArrayMap和HigherFuncArrayFilter两个block是一样的,但是为了区分它们的功能,还是建议这么做。

NSArray+HigherFunc.m 内容如下:

#import "NSArray+HigherFunc.h"

@implementation NSArray (HigherFunc)


- (HigherFuncArrayMap)map {
    
    HigherFuncArrayMap map = ^NSArray*(HigherFuncItemMap itemMap) {
        NSMutableArray *items = @[].mutableCopy;
        for (id item in self) {
            [items addObject:itemMap(item)];
        }
        return items;
    };
    return map;
}

- (HigherFuncArrayFilter)filter {
    HigherFuncArrayFilter filter = ^NSArray*(HigherFuncItemFilter itemFilter) {
        NSMutableArray *items = @[].mutableCopy;
        for (id item in self) {
            if (itemFilter(item)) {
                [items addObject:item];
            }
        }
        return items;
    };
    
    return filter;
}

#pragma mark -
#pragma mark 重写set方法防止外部修改实现 method
- (void)setMap:(HigherFuncArrayMap)map {}
- (void)setFilter:(HigherFuncArrayFilter)filter {}

@end

我们通过重写setter方法保证block不会被外部修改实现,并且在getter中遍历数组的元素并调用传入的执行代码来实现map和filter等功能。

使用

NSMutableArray *array = @[].mutableCopy;
[array addObject:@{@"name":@"jack",@"code":@1}];
[array addObject:@{@"name":@"judy",@"code":@2}];
[array addObject:@{@"name":@"judy",@"code":@3}];
[array addObject:@{@"name":@"mike",@"code":@4}];
    
NSArray *arr = array.map(^id(id item) {
    NSString *dic = item;
    NSString *name = [dic valueForKey:@"name"];
    return @{@"name": name};
});

NSLog(@">>>map:%@",arr);

arr = array.filter(^BOOL(id item) {
    NSDictionary *dic = item;
    NSInteger code = [[dic objectForKey:@"code"] integerValue];
    return code > 2;
});
NSLog(@">>>filter:%@",arr);

//运行结果
2018-08-31 13:00:46.759468+0800 BlockDemo[542:125803] >>>map:(
        {
        name = jack;
    },
        {
        name = judy;
    },
        {
        name = judy;
    },
        {
        name = mike;
    }
)
2018-08-31 13:00:46.759611+0800 BlockDemo[542:125803] >>>filter:(
        {
        code = 3;
        name = judy;
    },
        {
        code = 4;
        name = mike;
    }
)

由于语法上的限制,虽然这样的调用跟swift原生的调用对比起来还是复杂了,但通过block让oc实现了函数链式调用的代码看起来也清爽了很多

附上源代码地址:
https://github.com/guodunsong/HigherFuncDemo

上一篇:KVC的使用技巧

相关文章

网友评论

      本文标题:Block 实现高阶函数(map filter)

      本文链接:https://www.haomeiwen.com/subject/wgeswftx.html