iOS对象数组去重

刚接到公司需求,在一个显示数据的列表上,上拉加载更时后台返回的数组有可能出现部分重复,固将获取到的数据对应原数据去重后再添加。

用以下代码模拟原数据和新获取数据:

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.嵌套双重循环

    //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

2.对 arr2 进行遍历,将 arr2 中并存在于 arr1 中的对象删除

此方法先将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

3.对 arr2 进行遍历,将 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 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.将arr2先添加到arr1中 再对arr1中重复元素进行删除

方法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);

***以上  项目名称littleFunctions
 

(欢迎随手给一颗星星哦~)本篇博客Demo地址https://github.com/xmy0010/DemoForCSDN

本人邮箱18144200589@163.com欢迎小伙伴一起讨论,学习,进步。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值