I want to sort an array using NSSortDescriptor
IphoneNsarrayJquery Ui-SortableSortingIphone Problem Overview
I am having a problem regarding sorting an array w.r.t database:
NSSortDescriptor *sorter = [[NSSortDescriptor alloc] initWithKey:@"w" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject: sorter];
[mGlossaryArray sortUsingDescriptors:sortDescriptors];
[sorter release];
Here in database there are some first capital letters and because of that capital letter it does not show me proper sorted output. Here i am sorting an array with r.t "w" which is my table column in database. Here I have attach the screen shot for the output, which says that "Cancer" comes first than "c", but this is not correct, it is not giving alphabetically sort because of the capitalized words.
eg. if there is "able" in lower case and "aCid" then it will show aCid first and then able, and there is also a case where if the 1st letter is caps it comes first eg, "Able" and "a". Here Able displays first.
Iphone Solutions
Solution 1 - Iphone
Take a look here: Creating and Using Sort Descriptors
You can compare as case-insensitive.
NSSortDescriptor *sorter = [[[NSSortDescriptor alloc]
initWithKey:@"w"
ascending:YES
selector:@selector(localizedCaseInsensitiveCompare:)] autorelease];
NSArray *sortDescriptors = [NSArray arrayWithObject: sorter];
[mGlossaryArray sortUsingDescriptors:sortDescriptors];
Solution 2 - Iphone
Just use NSSortDescriptor like I used and It worked fine.
NSSortDescriptor * sortByRank = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES selector:@selector(caseInsensitiveCompare:)];
Solution 3 - Iphone
May I suggest using -localizedStandardCompare: (NSString)?
"This method should be used whenever file names or other strings are presented in lists and tables where Finder-like sorting is appropriate. The exact sorting behavior of this method is different under different locales and may be changed in future releases."
Solution 4 - Iphone
You may use this for sorting an array according to name thats also contains small letter:
NSSortDescriptor *sorter = [NSSortDescriptor sortDescriptorWithKey:@"w" ascending:YES selector:@selector(caseInsensitiveCompare:)];
NSArray *sortDescriptors = [NSArray arrayWithObject:sorter];
[mGlossaryArray sortUsingDescriptors:sortDescriptors];
This code work fine for me to sort name according to alphabets that has also small character i.e. rocky,Ajay,john,Bob etc.
Solution 5 - Iphone
I think this will do the trick for you. The docs for it are here: String Programming Guide
Add this little function written by Apple.
int finderSortWithLocale(id string1, id string2, void *locale)
{
static NSStringCompareOptions comparisonOptions =
NSCaseInsensitiveSearch | NSNumericSearch |
NSWidthInsensitiveSearch | NSForcedOrderingSearch;
NSRange string1Range = NSMakeRange(0, [string1 length]);
return [string1 compare:string2
options:comparisonOptions
range:string1Range
locale:(NSLocale *)locale];
}
Make sure that you copy the function definition into your header, or you'll get a compile error on your sorted array.
For your sorted array, use this method:
[mGlossaryArray sortedArrayUsingFunction:finderSortWithLocale context:[NSLocale currentLocale]];
Your results will look like this:
- c
- cabin
- cafe
- Cancer
- Chinese
- Christianity
- Christmas
- Coke
Solution 6 - Iphone
This code is working fine for me.
- (void)sortSearchResultWithInDocumentTypeArray:(NSMutableArray *)aResultArray basedOn:(NSString *)aSearchString {
NSSortDescriptor * frequencyDescriptor =[[NSSortDescriptor alloc] initWithKey:aSearchString ascending:YES comparator:^(id firstDocumentName, id secondDocumentName) {
static NSStringCompareOptions comparisonOptions =
NSCaseInsensitiveSearch | NSNumericSearch |
NSWidthInsensitiveSearch | NSForcedOrderingSearch;
return [firstDocumentName compare:secondDocumentName options:comparisonOptions];
}];
NSArray * descriptors = [NSArray arrayWithObjects:frequencyDescriptor, nil];
[aResultArray sortUsingDescriptors:descriptors];
}
Solution 7 - Iphone
An alternative form of Apple's finder sort with locale method uses the comparator block, helpful if you're in an ARC environment and don't want to deal with bridging casts, etc:
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"your_string_key" ascending:YES comparator:^NSComparisonResult(id obj1, id obj2) {
NSStringCompareOptions comparisonOptions = NSCaseInsensitiveSearch | NSNumericSearch | NSWidthInsensitiveSearch | NSForcedOrderingSearch;
NSRange string1Range = NSMakeRange(0, ((NSString *)obj1).length);
return [(NSString *)obj1 compare: (NSString *)obj2 options: comparisonOptions range: string1Range locale: [NSLocale currentLocale]];
}];
NSArray *sortedArray = [originalArray sortedArrayUsingDescriptors:@[sortDescriptor]];
I too would recommend storing the current locale in a local variable for efficiency purposes.