写在前面的
日常需求中我们经常需要对数组进行查询抽取等操作,每一次都是一大堆的for循环等等。以下是对NSArray的一些扩展以简化相关操作。
数据源
// model
Student {
name
age
sex
address
}
// 参赛选手
array = @[@{@"name":@"zhangsan",@"age":@"18",@"sex":@"man",@"address":@"Unit...."},
@{@"name":@"lisi",@"age":@"23",@"sex":@"woman",@"address":@"China...."},
@{@"name":@"wanger",@"age":@"45",@"sex":@"man",@"address":@"Germany...."},
@{@"name":@"mazi",@"age":@"32",@"sex":@"man",@"address":@"Unit...."}]
需求
1.找出array中年龄大于20岁的所有选手
NSArray *result = [array where:^BOOL(Student *student) {
return student.age >20;
}];
2.获取所有参赛选手的姓名
NSArray *result = [array select:^id(Student *student) {
return student.name;
}];
3.在每一个姓名后面加一个'-'或者'_' 并返回一个新数组
selectByCondition block1 = ^(Student *student){
return [NSString stringWithFormat:@"%@-", student.name];
};
selectByCondition block2 = ^(NSString *value){
return [NSString stringWithFormat:@"%@_", student.name];
};
NSArray *result = [array selectWithConditions:block1,block2,nil];
@[@"zhangsan-",@"lisi-"...@"zhangsan_",@"lisi_"];
4.查一下一个叫‘zhangsan’的信息
id obj = [self find:^BOOL(Student _Nonnull *student) {
return [student.name isEqualToString:@"zahngsan"];
}];
NSArray(quick) .h
typedef BOOL(^whereByCondition)(id target);
typedef BOOL(^findByCondition)(id target);
typedef id _Nonnull (^selectByCondition)(id target);
@interface NSArray (quik)
- (NSArray *)where:(whereByCondition)where;
- (NSArray *)select:(selectByCondition)select;
- (NSArray *)selectWithConditions:(selectByCondition)firstCondition,... NS_REQUIRES_NIL_TERMINATION;
- (id)find:(findByCondition)find;
@end
NSArray(quick) .m
@implementation NSArray(quick)
// find all
- (NSArray *)where:(whereByCondition)where {
NSMutableArray *tmp = [NSMutableArray arrayWithCapacity:self.count];
[self enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if (where(obj)) {
[tmp addObject:obj];
}
}];
return tmp;
}
- (NSArray *)select:(selectByCondition)select {
NSMutableArray *tmp = [NSMutableArray arrayWithCapacity:self.count];
[self enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if (select(obj)) {
[tmp addObject:select(obj)];
}
}];
return tmp;
}
- (NSArray *)selectWithConditions:(selectByCondition)firstCondition,... NS_REQUIRES_NIL_TERMINATION {
NSMutableArray *conditionArr = [NSMutableArray arrayWithCapacity:2];
NSMutableArray *tmp = [NSMutableArray arrayWithCapacity:self.count];
va_list argList;
id block;
if (firstCondition) {
[conditionArr addObject:firstCondition];
va_start(argList, firstCondition);
while ((block = va_arg(argList, id))) {
[conditionArr addObject:[block copy]];
}
va_end(argList);
}
[conditionArr enumerateObjectsUsingBlock:^(selectByCondition block, NSUInteger idx, BOOL * _Nonnull stop) {
[self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL * _Nonnull stop) {
if (block(obj)) {
[tmp addObject:block(obj)];
}
}];
}];
return tmp;
}
// find one
- (id)find:(findByCondition)find {
NSMutableArray *tmp = [NSMutableArray arrayWithCapacity:self.count];
[self enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if (find(obj)) {
[tmp addObject:obj];
*stop = YES;
}
}];
return tmp.count > 0?tmp[0]:nil;
}
@end