在項目開發過程中,往往會遇到這個問題:查找兩個數組相同的數據或者不同的數據,你會用下面三種中的哪種辦法實現呢?那種辦法會更好呢?
一 很多人都知道也最容易想到的是for循環,forin循環,block循環等其他的循環判斷數據中的元素相同不相同,如果找相同的數據一次雙層循環就可以,如果找不同的數據就需要兩次雙層循環.這里以block循環為例;
1 查找相同的數據
NSArray * arr2 = @[@4,@3,@2,@1];
NSArray * arr1 = @[@2,@3,@4,@5];
__block NSMutableArray *sameObject = [NSMutableArray arrayWithCapacity:5];
[arr2 enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSNumber *number1 = obj;
[arr1 enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if ([number1 isEqual:obj]) {
[sameObject addObject:number1];
*stop = YES;
}
}];
}];
NSLog(@"%@",sameObject);
打印信息:(4,3,2)
注:由觀察可以看出打印順序是按照arr2的順序打印的,解讀代碼之后可以
很容易得到結論:
打印順序是由外層循環的數組決定的;
2 查找不同的數據
NSArray * arr2 = @[@4,@3,@2,@1];
NSArray * arr1 = @[@2,@3,@4,@5];
__block NSMutableArray *difObject = [NSMutableArray arrayWithCapacity:5];
//找到arr2中有,arr1中沒有的數據
[arr2 enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSNumber *number1 = obj;//[obj objectAtIndex:idx];
__block BOOL isHave = NO;
[arr1 enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if ([number1 isEqual:obj]) {
isHave = YES;
*stop = YES;
}
}];
if (!isHave) {
[difObject addObject:obj];
}
}];
//找到arr1中有,arr2中沒有的數據
[arr1 enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSNumber *number1 = obj;//[obj objectAtIndex:idx];
__block BOOL isHave = NO;
[arr2 enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if ([number1 isEqual:obj]) {
isHave = YES;
*stop = YES;
}
}];
if (!isHave) {
[difObject addObject:obj];
}
}];
NSLog(@"%@",difObject);
打印信息:(1,5)
可以看到這種循環遍歷找出兩個數組的相同和不同的元素,代碼量有點多,我們就想有沒有簡單一點的方法呢?
二 有的人可能會想到用集合(NSSet)的相關方法,代碼如下:
1 查找相同的數據
NSArray *arr2 = @[@4,@3,@2,@1];
NSArray *arr1 = @[@2,@3,@4,@5];
NSMutableSet *set1 = [NSMutableSet setWithArray:arr1];
NSMutableSet *set2 = [NSMutableSet setWithArray:arr2];
[set1 intersectSet:set2];
NSLog(@"%@",set1);
打印結果: (3,4,2)
2 查找不同的數據
NSMutableSet *set1 = [NSMutableSet setWithArray:arr1];
NSMutableSet *set2 = [NSMutableSet setWithArray:arr2];
[set2 minusSet:set1];
NSMutableSet *set3 = [NSMutableSet setWithArray:arr2];
[set1 minusSet:set3];
[set2 unionSet:set1];
NSLog(@"%@",set2);
打印結果:(1,5)
注:這種辦法可以得到兩個數組中相同的數據,但是從打印出的結果看,得出的集合是無序的,這個是由集合的特性決定的,所以在實際開發過程中的應用相對較少.
三 運用正則的API得出兩個數組中相同與不同的數據
1 查找相同的數據
NSArray * arr2 = @[@4,@3,@2,@1];
NSArray * arr1 = @[@2,@3,@4,@5];
NSPredicate * filterPredicate_same = [NSPredicate predicateWithFormat:@"SELF IN %@",arr1];
NSArray * filter_no = [arr2 filteredArrayUsingPredicate:filterPredicate_same];
NSLog(@"%@",filter_no);
打印結果:(4,3,2)
2 查找不同的數據
NSArray * arr2 = @[@4,@3,@2,@1];
NSArray * arr1 = @[@2,@3,@4,@5];
//找到在arr2中不在數組arr1中的數據
NSPredicate * filterPredicate1 = [NSPredicate predicateWithFormat:@"NOT (SELF IN %@)",arr1];
NSArray * filter1 = [arr2 filteredArrayUsingPredicate:filterPredicate1];
//找到在arr1中不在數組arr2中的數據
NSPredicate * filterPredicate2 = [NSPredicate predicateWithFormat:@"NOT (SELF IN %@)",arr2];
NSArray * filter2 = [arr1 filteredArrayUsingPredicate:filterPredicate2];
//拼接數組
NSMutableArray *array = [NSMutableArray arrayWithArray:filter1];
[array addObjectsFromArray:filter2];
NSLog(@"%@",array);
打印信息:(1,5)
總結:第一種循環遍歷數組的方法可讀性和性能都不高;集合的辦法應用場景有一定的局限性;運用正則的方法可讀性高(推薦方法);