iOS开发技术分享iOS 开发 ios开发之路

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

2016-08-20  本文已影响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中的谓词搜素

上一篇下一篇

猜你喜欢

热点阅读