写了很长一段时间的Swift,现在转回OC,也想使用Swift里的函数式写法,就给OC数组扩展几个方法.
#import <Foundation/Foundation.h>
typedef id(^MapBlock)(id item);
typedef BOOL(^FilterBlock)(id item);
typedef NSComparisonResult(^SortedBlock)(id item1, id item2);
typedef void(^ForEachBlock)(NSUInteger i, id item);
typedef BOOL(^ContainsBlock)(id item);
@interface NSArray (FunctionalExtension)
@property(nonatomic, copy, readonly) NSArray* (^map)(MapBlock block);
@property(nonatomic, copy, readonly) NSArray* (^filter)(FilterBlock block);
@property(nonatomic, copy, readonly) NSArray* (^sorted)(SortedBlock block);
@property(nonatomic, copy, readonly) NSArray* (^forEach)(ForEachBlock block);
@property(nonatomic, copy, readonly) BOOL (^contains)(ContainsBlock block);
@end
@implementation NSArray (FunctionalExtension)
- (NSArray *(^)(MapBlock))map {
return ^(MapBlock b) {
NSMutableArray *a = [NSMutableArray arrayWithCapacity:self.count];
for (id obj in self) {
[a addObject:b(obj)];
}
return [a copy];
};
}
- (NSArray *(^)(FilterBlock))filter {
return ^(FilterBlock b) {
NSMutableArray *a = [NSMutableArray arrayWithCapacity:self.count];
for (id obj in self) {
if (b(obj)) {
[a addObject:obj];
}
}
return [a copy];
};
}
- (NSArray *(^)(SortedBlock))sorted {
return ^(SortedBlock b) {
return [self sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
return b(obj1, obj2);
}];
};
}
- (NSArray *(^)(ForEachBlock))forEach {
return ^(ForEachBlock b) {
for (NSUInteger i = 0; i < self.count; i++) {
b(i, self[i]);
}
return self;
};
}
- (BOOL(^)(ContainsBlock))contains {
return ^(ContainsBlock b) {
BOOL flag = NO;
for (id obj in self) {
if (b(obj)) {
flag = YES;
break;
}
}
return flag;
};
}
@end
使用:
NSArray *numberArray = @[@1, @11, @4, @3, @22, @2];
NSArray *newArray =
numberArray.filter(^BOOL(NSNumber *item) {
return item.integerValue < 22;
}).sorted(^NSComparisonResult(NSNumber *item1, NSNumber *item2) {
return item1 < item2;
}).map(^id(NSNumber *item) {
return [NSString stringWithFormat:@"%@", item];
}).forEach(^(NSUInteger i, id item) {
NSLog(@"%@", item);
});
BOOL isContain = newArray.contains(^BOOL(NSString *item) {
if ([item isEqualToString:@"100"]) {
return YES;
}
return NO;
});
NSLog(@"isContain => %d", isContain);