经常会遇到两个数组去对比然后进行去重的计算,看了网上很多文章,都是简单的两个数组的情况,很少有介绍两个模型数组的去重,于是自己写一点自己的经验吧。
首先准备一个模型对象,这里以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);
两种方法的计算结果对比很明显了,所以在遍历时尽量不要去做删除的操作。