美文网首页ios 知识点iOS Developer
在 objective-c 上玩玩函数式编程

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

作者: MarkNote | 来源:发表于2017-12-27 15:42 被阅读78次

    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 等高阶函数,可以减少循环的使用,同时让代码变得整洁。

    相关文章

      网友评论

      • wxiubin:想问下MNs自带的那几个文章为啥老是删掉了还会出现啊
        另外,咱敢不敢优化下界面啊,丑出一种风格了😭
        MarkNote:其实已经很漂亮啦。你看看那个Ulysses,就知道我的水平远在它之上 :sunglasses:

      本文标题:在 objective-c 上玩玩函数式编程

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