刚接到公司需求,在一个显示数据的列表上,上拉加载更时后台返回的数组有可能出现部分重复,固将获取到的数据对应原数据去重后再添加。
用以下代码模拟原数据和新获取数据:
NSMutableArray *origin_arr1 = @[].mutableCopy;
for (int i = 0; i < 1000; i++) {
Person *person = [[Person alloc] init];
person.name = [NSString stringWithFormat:@"name_%d",i];
person.ID = [NSString stringWithFormat:@"ID_%d",i];
[origin_arr1 addObject:person];
}
NSMutableArray *origin_arr2 = @[].mutableCopy;
for (int i = 0; i < 2000; i++) {
if (i % 2 == 0) {
Person *person = [[Person alloc] init];
person.name = [NSString stringWithFormat:@"name_%d",i];
person.ID = [NSString stringWithFormat:@"ID_%d",i];
[origin_arr2 addObject:person];
}
}
//1.嵌套for循环
NSMutableArray *arr1 = origin_arr1.mutableCopy;
NSMutableArray *arr2 = origin_arr2.mutableCopy;
CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent();
for (Person *person in arr2) {
BOOL isRepeat = NO;
for (Person *anotherPerson in arr1) {
if ([person.ID isEqualToString:anotherPerson.ID]) {
isRepeat = YES;
break;
}
}
if (!isRepeat) {
[arr1 addObject:person];
}
}
CFAbsoluteTime linkTime = (CFAbsoluteTimeGetCurrent() - startTime);
NSLog(@"方法1计算时长 : %f ms", linkTime *1000.0);
此方法优点是逻辑明了,缺点是时间复杂度太大。运行三次耗时如下:
2021-09-29 15:59:48.297226+0800 littleFunctions[6684:891503] 方法1计算时长 : 52.940965 ms
2021-09-29 15:59:56.902128+0800 littleFunctions[6684:891503] 方法1计算时长 : 58.038950 ms
2021-09-29 15:59:57.783826+0800 littleFunctions[6684:891503] 方法1计算时长 : 54.998994 ms
此方法先将arr1置于一个字典中,遍历arr2的时候通过键值对的方式查找重复数据并将其删除,实现代码如下:
//2.对 arr2 进行遍历,将 arr2 中并存在于 arr1 中的对象删除;
arr1 = origin_arr1.mutableCopy;
arr2 = origin_arr2.mutableCopy;
startTime = CFAbsoluteTimeGetCurrent();
NSMutableDictionary *dic = @{}.mutableCopy;
for (Person *person in arr1) {
[dic setObject:person forKey:person.ID];
}
[arr2 enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(Person *person, NSUInteger idx, BOOL * _Nonnull stop) {
Person *dic_person = dic[person.ID];
if (dic_person) {
[arr2 removeObject:person];
}
}];
[arr1 addObjectsFromArray:arr2];
linkTime = (CFAbsoluteTimeGetCurrent() - startTime);
NSLog(@"方法2计算时长 : %f ms", linkTime *1000.0);
此方法耗时与方法1有10倍级别差距,但由于在遍历的时候做了删除操作,实际上还是不太美好,可以有更加优化的做法。该方法耗时如下:
2021-09-29 16:01:45.407913+0800 littleFunctions[6686:892116] 方法2计算时长 : 7.753968 ms
2021-09-29 16:01:47.357706+0800 littleFunctions[6686:892116] 方法2计算时长 : 7.776976 ms
2021-09-29 16:01:48.634885+0800 littleFunctions[6686:892116] 方法2计算时长 : 9.027004 ms
此方法可以避免在遍历时对本数组做删除操作,然后在遍历结束后用arr1添加新的数组即可:
//3.对 arr2 进行遍历,将 arr2 中不存在于 arr1 中的对象保存到新的数组中;
NSMutableArray *arr1 = origin_arr1.mutableCopy;
NSMutableArray *arr2 = origin_arr2.mutableCopy;
CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent();
NSMutableDictionary *dic = @{}.mutableCopy;
for (Person *person in arr1) {
[dic setObject:person forKey:person.ID];
}
NSMutableArray *newArr = @[].mutableCopy;
[arr2 enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(Person *person, NSUInteger idx, BOOL * _Nonnull stop) {
Person *dic_person = dic[person.ID];
if (!dic_person) {
[newArr addObject:person];
}
}];
[arr1 addObjectsFromArray:newArr];
CFAbsoluteTime linkTime = (CFAbsoluteTimeGetCurrent() - startTime);
NSLog(@"方法3计算时长 : %f ms", linkTime *1000.0);
该方法耗时最少:
2021-09-29 16:04:54.495735+0800 littleFunctions[6693:893402] 方法3计算时长 : 1.036048 ms
2021-09-29 16:04:55.287229+0800 littleFunctions[6693:893402] 方法3计算时长 : 1.014948 ms
2021-09-29 16:04:55.956728+0800 littleFunctions[6693:893402] 方法3计算时长 : 0.971079 ms
方法3其实可以再优化一些,因为遍历arr2的时候,将目标对象放入新数组,遍历完成后加入arr1,可以直接在遍历的时候用arr1就添加上这些目标对象
//3.对 arr2 进行遍历,将 arr2 中不存在于 arr1 中的对象保存到新的数组中;
NSMutableArray *arr1 = origin_arr1.mutableCopy;
NSMutableArray *arr2 = origin_arr2.mutableCopy;
CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent();
NSMutableDictionary *dic = @{}.mutableCopy;
for (Person *person in arr1) {
[dic setObject:person forKey:person.ID];
}
// NSMutableArray *newArr = @[].mutableCopy;
[arr2 enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(Person *person, NSUInteger idx, BOOL * _Nonnull stop) {
Person *dic_person = dic[person.ID];
if (!dic_person) {
// [newArr addObject:person];
[arr1 addObject:person];
}
}];
// [arr1 addObjectsFromArray:newArr];
CFAbsoluteTime linkTime = (CFAbsoluteTimeGetCurrent() - startTime);
NSLog(@"方法3计算时长 : %f ms", linkTime *1000.0);
方法4说起来还不如方法2,但是该方法适用于另外一个场景,就是我们目前只有一个数组,需要从这个数组中找出重复元素并删除多余的。
//4.将arr2先添加到arr1中 再对arr1中重复元素进行删除
arr1 = origin_arr1.mutableCopy;
arr2 = origin_arr2.mutableCopy;
startTime = CFAbsoluteTimeGetCurrent();
[arr1 addObjectsFromArray:arr2];
dic = @{}.mutableCopy;
[arr1 enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(Person *person, NSUInteger idx, BOOL * _Nonnull stop) {
Person *dic_person = dic[person.ID];
if (!dic_person) {
[dic setObject:person forKey:person.ID];
} else {
[arr1 removeObject:dic_person];
}
}];
linkTime = (CFAbsoluteTimeGetCurrent() - startTime);
NSLog(@"方法4计算时长 : %f ms", linkTime *1000.0);
(欢迎随手给一颗星星哦~)本篇博客Demo地址https://github.com/xmy0010/DemoForCSDN
本人邮箱[email protected]欢迎小伙伴一起讨论,学习,进步。