Reputation: 1981
I have a NSArray of countries that I obtained using [NSLocale ISOCountryCodes]
. How do I sort this NSArray such that I can put certain commonly used countries at the top of the list, while keeping the rest in its alphabetical order?
United States of America
United Kingdom
Singapore
Korea
Japan
Hong Kong
Afghanistan
Albania
Algeria
etc etc..
I am using caseInsensitiveCompare:
currently to get the alphabetical order, but how can I change it such that I can specify a list to put at the top, while the rest to be kept alphabetical below.
Upvotes: 1
Views: 237
Reputation: 6893
I would do it using Sort Descriptor. I don't like manipulating array again and again. So, I find sort descriptors best in this kind of scenario. (Just personal preference)
Step 1: Create a model class with priority as a key. My model class-
#import <Foundation/Foundation.h>
@interface ISOCountry : NSObject
@property(nonatomic, strong) NSString *countryCode;
@property(nonatomic, retain) NSString *priority;
@end
Step 2: The just do this-
NSArray *ISOCountryCodes = [[NSArray alloc]initWithArray:[NSLocale ISOCountryCodes]];
NSArray *commonUsedCountries= [[NSArray alloc]initWithObjects:@"NR", @"NG", @"KW", @"ES", nil];
NSMutableArray *arrayToBeSorted = [[NSMutableArray alloc]init];
for(NSString *countryCode in ISOCountryCodes){
ISOCountry *isoCountry = [[ISOCountry alloc] init];
[isoCountry setValue:countryCode forKey:@"countryCode"];
if(![commonUsedCountries containsObject:countryCode]){
[isoCountry setValue:[NSString stringWithFormat:@"%d", 2] forKey:@"priority"];
}
else{
[isoCountry setValue:[NSString stringWithFormat:@"%d", 1] forKey:@"priority"];
}
[arrayToBeSorted addObject:isoCountry];
}
NSSortDescriptor *prioritySort = [[NSSortDescriptor alloc] initWithKey:@"priority" ascending:YES];
NSSortDescriptor *countryCodeSort = [[NSSortDescriptor alloc] initWithKey:@"countryCode" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObjects:prioritySort, countryCodeSort, nil];
NSArray *sortedArray = [arrayToBeSorted sortedArrayUsingDescriptors:sortDescriptors];
Upvotes: 1
Reputation: 1317
As opposed to WenchenHuang's answer (which is valid), I think you could do it with the help of sortedArrayUsingComparator
.
Inside the block just compare the strings as usually, but if the string equals to one of the codes that you want to show higher, return YES
.
someArray = [someArray sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
if ([(NSString*)obj1 isEqualToString:@"USA"]) {
return YES;
} else if ([(NSString*)obj1 isEqualToString:@"SOME_OTHER_COUNTRY"]) {
return YES;
}
return [(NSString*)obj1 compare:(NSString*)obj2];
}];
Upvotes: 1
Reputation: 24714
You can delete the objects you do not want to sort,then sort the rest,then add them together. Example Code:
NSMutableArray * allData = [[NSMutableArray alloc] initWithArray:[[NSLocale ISOCountryCodes]]];
NSArray * yourexceptArray;
[allData removeObjectsInArray:yourexceptArray];
NSMutableArray * result = [[NSMutableArray alloc] initWithArray:yourexcepArray];
sortedArray = //Sort the allData as you like,then add it to result
[result addObjectsFromArray:sortedArray]
Upvotes: 1