起因
經(jīng)常處理數(shù)據(jù)的時(shí)候 會(huì)遇到這樣的問題脖阵。
看到其他語言如swift 或者python 都有自己的map filter 的語法,OC卻要用for 語句
1.網(wǎng)絡(luò)請求的數(shù)據(jù),需要數(shù)組中第幾個(gè)元素進(jìn)行計(jì)算
2.需要滿足部分的元素形成一個(gè)新的數(shù)組
一般關(guān)于這兩個(gè)問題的反映是用for 數(shù)組 蔫仙,然后new 一個(gè)新的可變數(shù)組把符合條件的數(shù)據(jù)加入到數(shù)組中
NSMutableArray *marr = [NSMutableArray array];
for (int i = 0 ; i < array.count; i++) {
id temp = array[i];
if(temp 滿足條件) {
[marr addobject:temp];
這個(gè)時(shí)候 得到了一個(gè)滿足條件的數(shù)組
}
}
簡單的還好哀卫,如果涉及很多需要滿足條件的計(jì)算 巨坊,這樣的代碼可讀性和維護(hù)性,都非常的有挑戰(zhàn)此改。
方案一
把for 的語句封裝起來
方案二
添加NSArray的Category
*.h 文件
#import <Foundation/Foundation.h>
typedef BOOL(^filterCondition)(id target);
typedef id (^mapCondition)(id target);
@interface NSArray (Common)
- (NSArray *)reverse;
/// 篩選出所有符合條件的元素
/// @param condition 篩選條件
- (NSArray *)filter:(filterCondition)condition;
/// 篩選出前幾個(gè)符合條件的元素
/// @param condition 篩選條件
/// @param count 需要的數(shù)量
- (NSArray *)filter:(filterCondition)condition theTopServeral:(NSUInteger)count;
/// 篩選出后幾個(gè)符合條件的元素
/// @param condition 篩選條件
/// @param count 需要的數(shù)量
- (NSArray *)filter:(filterCondition)condition theEndServeral:(NSUInteger)count;
/// map遍歷
- (NSArray *)map:(mapCondition)condition;
@end
*.m 文件
#import "NSArray+Common.h"
@implementation NSArray (Common)
- (NSArray *)reverse {
return [[[NSMutableArray arrayWithArray:self] reverseObjectEnumerator] allObjects];
}
- (NSArray *)filter:(filterCondition)condition {
return [self filter:condition needCount:self.count isTopSeveral:YES];
}
- (NSArray *)filter:(filterCondition)condition theTopServeral:(NSUInteger)count {
return [self filter:condition needCount:count isTopSeveral:YES];
}
- (NSArray *)filter:(filterCondition)condition theEndServeral:(NSUInteger)count {
return [self filter:condition needCount:count isTopSeveral:NO];
}
- (NSArray *)filter:(filterCondition)condition needCount:(NSUInteger)count isTopSeveral:(BOOL)isTopSeveral {
if (count < 1) {
return @[];
}
NSMutableArray *tmp = [NSMutableArray arrayWithCapacity:self.count];
[self enumerateObjectsWithOptions:isTopSeveral ? NSEnumerationConcurrent : NSEnumerationReverse usingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if (tmp.count >= count - 1) {
*stop = YES;
}
if (condition(obj)) {
[tmp addObject:obj];
}
}];
return tmp.copy;
}
- (NSArray *)map:(mapCondition)condition {
if (!self.count) {
return self;
}
NSMutableArray *tmp = [NSMutableArray arrayWithCapacity:self.count];
[self enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if (condition(obj)) {
[tmp addObject:condition(obj)];
} else {
#ifdef DEBUG
NSString *tipString = [NSString stringWithFormat:@"元素不符合遍歷條件,index = %ld, 元素:%@", idx, obj];
NSAssert(NO, tipString);
#endif
}
}];
return tmp.copy;
}
@end
代碼的核心 一句 就是enumerateObjectsUsingBlock
使用方法
這里的target 是id 類型趾撵,可以是網(wǎng)絡(luò)請求下來的model ,也可以是字符串 int 等類型
直接返回 float
NSArray *arr = @[@"asd",@"bcd3",@"aew",@"zxc",@"123",@"567",@"bnj",@"opi",@"tytreu",@"qwerty",@"12"];
NSArray *sortArray = [arr filter:^BOOL(NSString * target) {
return target.length > 2;
}];
NSLog(@"print array - %@",sortArray);
NSArray *topSerArr = [arr filter:^BOOL(NSString * target) {
return target.length > 2;
} theTopServeral:4];
NSLog(@"print tio serveral array - %@",topSerArr);
通過block 的內(nèi)部條件進(jìn)行數(shù)據(jù)篩選,把篩選條件明確的展示在最顯眼的位置
總結(jié)
這個(gè)優(yōu)化雖然和小占调,但是一個(gè)大型項(xiàng)目恰恰是每一處的優(yōu)化才帶來整體的效率提升暂题。