如何去除IOS数组中重复的数据?
相信每个软件开发都会遇到这样的问题,我也不例外,而且遇到好多次,之前每次都用相同的方法,无非是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中的谓词搜素