NSArray快速查询、重组

1,413 阅读1分钟

写在前面的

日常需求中我们经常需要对数组进行查询抽取等操作,每一次都是一大堆的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

后续有需要会随时更新、有问题随时沟通,欢迎指正~~~