ios 知识点iOS Developer

在 objective-c 上玩玩函数式编程

2017-12-27  本文已影响78人  MarkNote

tags:ios

每一个iOS开发者都有很多纠结的事。即使对老手而言也是如此。每做一个新的 feature 都要纠结一下是用 obj-c 还是 swift 来写。这种纠结随着 swift 的成熟而与日俱增。

技术选型犹如采购电子产品,用新不用旧,新项目自然倾向于用 swift 。无奈手头的应用有很多基于 obj-c ,不可能完全重写。而 obj-c 与 swift 混编虽然可行,却不是我想走的方向。一来无端的给应用增加了一些不必要的东西,二来频繁在 obj-c 与 swift 之间来回切换给心灵带来的冲击实在太大,毕竟二者的范式不同。

如此看来,让基于 obj-c 的开发更舒坦一点是很有意义的。swift 的若干语言特性中,对函数式编程编程的友好支持是让人心动的。其实在 obj-c 中,也可以做到类似的效果。有一些第三方的库,比如RXCollections,可以在这方面帮我们。然而我不太喜欢RXCollections中方法的命名。 自己简单的整了一下,可以愉快的玩玩了。

头文件声明

#import <Foundation/Foundation.h>
@interface NSArray (FP)
- (NSArray *)filter:(BOOL (^)(id obj, NSUInteger idx, BOOL *stop))predicate;
- (NSArray *) sort:( NSComparisonResult (^)(id obj1, id obj2)) block;
- (NSArray *)map:(id(^)(id))block;
- (id) reduce:(id (^)(id memo, id obj)) block withInitialMemo:(id) memo;
@end

实现文件

#import "NSArray+FP.h"

@implementation NSArray (FP)

- (NSArray *)filter:(BOOL (^)(id obj, NSUInteger idx, BOOL *stop))predicate {
    NSIndexSet * filteredIndexes = [self indexesOfObjectsPassingTest:predicate];
    return [self objectsAtIndexes:filteredIndexes];
}

- (NSArray *)map:(id(^)(id))block {
    NSMutableArray * newArray = [NSMutableArray array];
    for (id item in self) {
        id obj = block(item);
        [newArray addObject:obj];
    }
    NSArray *arrReturn = [NSArray arrayWithArray:newArray];
    [newArray removeAllObjects];
    return arrReturn;
}

- (NSArray *) sort:( NSComparisonResult (^)(id obj1, id obj2)) block {
    return [self sortedArrayUsingComparator:block];
}

- (id) reduce:(id (^)(id memo, id obj)) block withInitialMemo:(id) memo {
    for (id obj in self) {
        memo = block(memo, obj);
    }
    return memo;
}

@end

使用

filter

   NSArray * allRemovedRecords = [allRecords filter:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
        CKRecord *record = (CKRecord *) obj;
        //NSString *filename = [self generateFileName:record];
        if(record[@"status"] && [kRemoved isEqualToString:record[@"status"]]){
            return YES;
        } else {
            return NO;
        }
    }];

map

return [files map:^id(id item) {
        NSString * fileName = (NSString *) item;
        return [fileName stringByDeletingPathExtension];
    }];

sort

NSArray *sortedKeys = [[tags allKeys] sort:^NSComparisonResult(id a, id b) {
        NSString *s1 = (NSString *) a;
        NSString *s2 = (NSString *) b;
        if([s1 isEqualToString:T(@"All")]){
            return -1;
        } else if([s2 isEqualToString:T(@"All")]){
            return 1;
        } else {
            return [a compare:b];
        }
    }];

总结

以上通过对 NSArray 做的category 为例,实现了filter,sort,map,reduce 等高阶函数,可以减少循环的使用,同时让代码变得整洁。

上一篇下一篇

猜你喜欢

热点阅读