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

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 14,532评论 4 61
  • 转载自:https://github.com/Tim9Liu9/TimLiu-iOS 目录 UI下拉刷新模糊效果A...
    袁俊亮技术博客阅读 12,133评论 9 105
  • 去年12月,女儿因为肺炎而住院。之前连续六天高烧,之后五天住院,搞得我灰头土脸,疲惫不堪。陪护的我,自责、困顿,加...
    共剪西窗烛阅读 1,571评论 0 3
  • #打卡# 05月26日 周五 天气多云 身体状态8.6分 【我的进度】日跑2公里第334天,先坚持1年;每日5点...
    龙马行天下阅读 203评论 0 1
  • 每每遇到合适的人,总会将自己的梦想激情满满地向他们描绘一遍,好像在这过程中那个美好的梦似乎已经实现,自己似乎变得与...
    飞翔的饼阅读 363评论 0 1

友情链接更多精彩内容