多种方法对iOS数组中的元素去重复
例如:
1 2 3 | NSArray *array = @[@"12-11", @"12-11", @"12-11", @"12-12", @"12-13", @"12-14"]; |
参考答案:
- 第一种方法:开辟新的内存空间,然后判断是否存在,若不存在则添加到数组中,得到最终结果的顺序不发生变化。效率分析:时间复杂度为O ( n2 ):
1 2 3 4 5 6 7 8 9 10 11 12 | NSMutableArray *resultArray = [[NSMutableArray alloc] initWithCapacity:array.count]; // 外层一个循环 for (NSString *item in array) { // 调用-containsObject:本质也是要循环去判断,因此本质上是双层遍历 // 时间复杂度为O ( n^2 )而不是O (n) if (![resultArray containsObject:item]) { [resultArray addObject:item]; } } NSLog(@"resultArray: %@", resultArray); |
补充:原来集合操作可以通过valueForKeyPath来实现的,去重可以一行代码实现:
1 2 3 4 | array = [array valueForKeyPath:@"@distinctUnionOfObjects.self"]; NSLog(@"%@", array); |
但是返回的结果是无序的,与原来的顺序不同。大家可以阅读:Collection Operators
- 第二种方法:利用NSDictionary去重,字典在设置key-value时,若已存在则更新值,若不存在则插入值,然后获取allValues。若不要求有序,则可以采用此种方法。若要求有序,还得进行排序。效率分析:只需要一个循环就可以完成放入字典,若不要求有序,时间复杂度为O(n)。若要求排序,则效率与排序算法有关:
1 2 3 4 5 6 7 8 | NSMutableDictionary *resultDict = [[NSMutableDictionary alloc] initWithCapacity:array.count]; for (NSString *item in array) { [resultDict setObject:item forKey:item]; } NSArray *resultArray = resultDict.allValues; NSLog(@"%@", resultArray); |
如果需要按照原来的升序排序,可以这样:
1 2 3 4 5 6 7 8 | resultArray = [resultArray sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1,id _Nonnull obj2) { NSString *item1 = obj1; NSString *item2 = obj2; return [item1 compare:item2 options:NSLiteralSearch]; }]; NSLog(@"%@", resultArray); |
- 第三种方法:利用集合NSSet的特性(确定性、无序性、互异性),放入集合就自动去重了。但是它与字典拥有同样的无序性,所得结果顺序不再与原来一样。如果不要求有序,使用此方法与字典的效率应该是差不多的。效率分析:时间复杂度为O (n):
1 2 3 4 5 | NSSet *set = [NSSet setWithArray:array]; NSArray *resultArray = [set allObjects]; NSLog(@"%@", resultArray); |
如果要求有序,那就得排序,比如这里要升序排序:
1 2 3 4 5 6 7 8 | resultArray = [resultArray sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1,id _Nonnull obj2) { NSString *item1 = obj1; NSString *item2 = obj2; return [item1 compare:item2 options:NSLiteralSearch]; }]; NSLog(@"%@", resultArray); |
补充:
一直没有使用过有序集合,网友们反馈到可以直接使用有序集合,感谢大家:
1 2 3 4 | NSOrderedSet *set = [NSOrderedSet orderedSetWithArray:array]; NSLog(@"%@", set.array); |
以上三种方法是笔者所能想到的办法。如果大家有更好的办法,欢迎在评论中指出。
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。
- 上一篇: C++局部变量和全局变量
- 下一篇: java折半查找法 查找数组中与目标数最接近的数