iOS进阶之两个模型数组的去重方法

  经常会遇到两个数组去对比然后进行去重的计算,看了网上很多文章,都是简单的两个数组的情况,很少有介绍两个模型数组的去重,于是自己写一点自己的经验吧。

  首先准备一个模型对象,这里以Person为例,对象拥有name属性:

@interface Person : NSObject

/** 姓名 */
@property(nonatomic, copy) NSString *name;

@end

  然后分别准备两个模型数组,存放一些模型数据:

    NSMutableArray *arr_1 = [NSMutableArray array];
    for (NSInteger i = 0; i < 1000; i++) {
        Person *p = [[Person alloc] init];
        p.name = [NSString stringWithFormat:@"name_%zd", i];
        [arr_1 addObject:p];
    }
    
    NSMutableArray *arr_2 = [NSMutableArray array];
    for (NSInteger i = 0; i < 1000; i++) {
        if (i % 2 == 0) {
            Person *p = [[Person alloc] init];
            p.name = [NSString stringWithFormat:@"name_%zd", i];
            [arr_2 addObject:p];
        }
    }

  这里为了让计算效率更明显,所以arr_1存放了1000个对象。

  这里不推荐使用嵌套for循环,所以下面就没有写这种方法,当然也可以自行去验证嵌套for循环的效率。

  去重说明:在 arr_1 中去重 arr_2 中已有的对象

  去重操作前提:将 arr_2 中的对象保存到一个字典中,这样之后直接利用键值进行查找

    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    for (Person *p in arr_2) {
        [dict setObject:p.name forKey:p.name];
    }

  去重方法一:使用数组的 enumerateObjectsUsingBlock: 方法对 arr_1 进行遍历,将 arr_1 中并存在于 arr_2 中的对象删除,去重结果保存在 arr_1 中;

    CFAbsoluteTime startTime =CFAbsoluteTimeGetCurrent();
    
    // 这里是运行三次的结果
    // 计算时长 : 2.709031 ms
    // 计算时长 : 2.907991 ms
    // 计算时长 : 2.711058 ms
    [arr_1 enumerateObjectsUsingBlock:^(Person *p, NSUInteger idx, BOOL * _Nonnull stop) {
        NSString *name = [dict objectForKey:p.name];
        if (name.length > 0) {
            [arr_1 removeObject:p];
        }
    }];
    
    CFAbsoluteTime linkTime = (CFAbsoluteTimeGetCurrent() - startTime);
    NSLog(@"计算时长 : %f ms", linkTime *1000.0);

  去重方法二:使用数组的 enumerateObjectsUsingBlock: 方法对 arr_1 进行遍历,将 arr_1 中并存在于 arr_2 中的对象保存到新的数组中,去重结果保存在 newArr 中;

    CFAbsoluteTime startTime =CFAbsoluteTimeGetCurrent();
    
    // 这里是运行三次的结果
    // 计算时长 : 0.548959 ms
    // 计算时长 : 0.308037 ms
    // 计算时长 : 0.313997 ms
    NSMutableArray *newArr = [NSMutableArray array];
    [arr_1 enumerateObjectsUsingBlock:^(Person *p, NSUInteger idx, BOOL * _Nonnull stop) {
        NSString *name = [dict objectForKey:p.name];
        if (name.length <= 0) {
            [newArr addObject:p];
        }
    }];
    
    CFAbsoluteTime linkTime = (CFAbsoluteTimeGetCurrent() - startTime);
    NSLog(@"计算时长 : %f ms", linkTime *1000.0);

  两种方法的计算结果对比很明显了,所以在遍历时尽量不要去做删除的操作。

posted @ 2019-07-25 12:07  兔.小白  阅读(3636)  评论(0编辑  收藏  举报