美文网首页iOS开发技术分享iOS 开发 ios开发之路
如何去除IOS数组中重复的数据?

如何去除IOS数组中重复的数据?

作者: 张付东 | 来源:发表于2016-08-20 23:49 被阅读1221次

    相信每个软件开发都会遇到这样的问题,我也不例外,而且遇到好多次,之前每次都用相同的方法,无非是for循环或者是containsObject之类的,虽说后者很好用,但建议还是多了解一些其它的方法,拓展一下自己的知识面。

    现在有如下几种方法:

    1:首先就说说比较常用的 - (BOOL)containsObject:(ObjectType)anObject;
    代码如下:

    NSArray*  array = @[@"9",@"1",@"5",@"6",@"5",
                                     @"2",@"8",@"7",@"3",@"0",
                                     @"5",@"6",@"4",@"8"];
      
    NSMutableArray* temp = [[NSMutableArray alloc] init];
        for (NSString** str in array)
        {
           if (![temp containsObject:str])
            {
                [temp addObject:str];
            }
        }
        NSLog(@"temp:%@",temp);
    
    // 打印如下:
    temp:(
        9,  1,  5,  6,  2,  8,  7,  3,  0,  4
    )
    

    2:第二种也就是for循环,推荐方法:先给数组排序,然后再去重(方法自己参考着写)

    3:利用NSSet集合的方法
    代码如下:

    NSArray*  array = @[@"9",@"1",@"5",@"6",@"5",
                                   @"2",@"8",@"7",@"3",@"0",
                                   @"5",@"6",@"4",@"8"];
    
     NSSet* set = [[NSSet alloc] initWithArray:array];
        NSLog(@"set:%@",[set allObjects]);
    
    // 打印如下:
    set:(
        2,  3,  4, 5, 6, 7, 0, 8, 1,  9
    )
    

    由打印结果可以看出,虽然已经把重复的数据去掉了。但是又会出现一个新的问题,就是NSSet集合的数据本来就是数据的无序集合,所以筛选出来的数据,是无序的,根据不同的需求,个人建议,还是最好输出有序的数据集合,这样对数据的选择不会有太多的问题,以免之后遇到类似的坑,所以针对NSSet的无序集合,出现了一个相对的NSOrderedSet的有序结合。

    4: NSOrderedSet的有序集合
    代码如下:

    NSArray*  array = @[@"9",@"1",@"5",@"6",@"5",
                                   @"2",@"8",@"7",@"3",@"0",
                                   @"5",@"6",@"4",@"8"];
    
    NSOrderedSet * orderSet = [[NSOrderedSet alloc] initWithArray:array];
    NSLog(@"orderSet:%@",orderSet); 
    
    // 打印如下:
    **orderSet**:{(
        9, 1, 5, 6, 2, 8, 7, 3, 0, 4
    )}
    

    5: 利用 - (void)setValue:(nullable ObjectType)value forKey:(NSString *)key
    代码如下:

    NSArray**  array = @[@"9",@"1",@"5",@"6",@"5",
                                   @"2",@"8",@"7",@"3",@"0",
                                   @"5",@"6",@"4",@"8"];
    
    NSMutableDictionary* dic = [[NSMutableDictionary alloc] init];
        for (NSString* string in array)
        {
            [dic setValue:string forKey:string];
        }
        NSLog(@"dic:%@",[dic allKeys]);
     
    // 打印如下:
    **dic**:(
        7, 3, 8, 4, 0, 9, 5, 1, 6,  2
    )
    

    这个方法打印出来也是乱序的,具体用这个方法如何打印出来有序的,暂时还没想到,如有需求,请参考方法1和方法4.

    6: 这个方法,也是在网上查的,就是所谓的键值编码(KVO)
    代码如下:

    NSArray*  array = @[@"9",@"1",@"5",@"6",@"5",
                                   @"2",@"8",@"7",@"3",@"0",
                                   @"5",@"6",@"4",@"8"];
    
    array = [array valueForKeyPath:@"@distinctUnionOfObjects.self"];
        NSLog(@"array: %@",array);
    
    // 打印如下:
    array: (
        2,  3, 4, 5, 6, 7, 0,  8, 1,  9
    )
    

    这个方法输出的也是无序的,所以如果需要输入有序的数据,请参考方法1和方法4.

    7: 使用block 块遍历整个数组:

       NSArray*  array = @[@"9",@"1",@"5",@"6",@"5",
                            @"2",@"8",@"7",@"3",@"0",
                            @"5",@"6",@"4",@"8"];
        
       NSMutableArray* tempArray = [[NSMutableArray alloc] init];
       [array enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
    
            if (![tempArray containsObject:obj]) {
                [tempArray addObject:obj];
            }
            NSLog(@"%lu is %@",(unsigned long)idx,obj);
            // *stop = YES; (下面有解释)
        }];
       NSLog(@"tempArray:%@",tempArray);
        
       /**
         *  备注: enumerateObjectsUsingBlock(有三个参数,如下解释)
         *    1: obj: 当前对象 (这里声明数组里面你放入的是什么类型的东西,不确定的话就直接id类型最靠谱)
         *    2: inx: 其索引 (数组的下标 )
         *    3:stop: 引用的Boolen值(这个bool值,决定是否继续循环。如果有NO,继续循环下去。如果为YES ,停止循环)
         */
    
    
    打印如下:
    2016-12-17 13:48:28.057 myProject[745:27588] 0 is 9
    2016-12-17 13:48:28.057 myProject[745:27588] 1 is 1
    2016-12-17 13:48:28.057 myProject[745:27588] 2 is 5
    2016-12-17 13:48:28.057 myProject[745:27588] 3 is 6
    2016-12-17 13:48:28.057 myProject[745:27588] 4 is 5
    2016-12-17 13:48:28.057 myProject[745:27588] 5 is 2
    2016-12-17 13:48:28.058 myProject[745:27588] 6 is 8
    2016-12-17 13:48:28.058 myProject[745:27588] 7 is 7
    2016-12-17 13:48:28.058 myProject[745:27588] 8 is 3
    2016-12-17 13:48:28.058 myProject[745:27588] 9 is 0
    2016-12-17 13:48:28.058 myProject[745:27588] 10 is 5
    2016-12-17 13:48:28.058 myProject[745:27588] 11 is 6
    2016-12-17 13:48:28.059 myProject[745:27588] 12 is 4
    2016-12-17 13:48:28.059 myProject[745:27588] 13 is 8
    
    2016-12-17 13:48:28.059 myProject[745:27588] tempArray:(
        9, 1,  5,  6,  2, 8,  7,  3, 0, 4
    )
     
    

    这个方法输出的也是有序的,但是有点繁琐,建议使用方法1和方法4.

    8: 谓词搜索 (筛选两个数组之间的异同,谓词搜索可以结合SQL操作,具体讲解下方有参考链接)

     /**
      *  获取两个数组之间的相同元素:@"(SELF IN %@)"
      */
     NSArray *filterArray = @[@"1", @"2",@"3"];
     NSArray *array = @[@"0", @"1", @"2", @"4",@"5"];
     NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NOT (SELF IN %@)", filterArray]; 
     NSLog(@"%@", [array filteredArrayUsingPredicate:predicate]);
    
    打印结果:
    2016-12-17 14:29:28.059 myProject[879:52365] (
        1,  2
    )
    
    

    关于KVO,其实是很好用的,如果有深入了解的,有个链接,可以参考一下,里面有很多常用的方法。

    本文参考链接如下,谢谢提供的分享:
    数组去重方法分享链接
    KVO知识分享链接
    NSArray数组的用法
    IOS中的谓词搜素

    相关文章

      网友评论

        本文标题:如何去除IOS数组中重复的数据?

        本文链接:https://www.haomeiwen.com/subject/uwzbsttx.html