I want to sort an array using NSSortDescriptor

IphoneNsarrayJquery Ui-SortableSorting

Iphone 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.enter image description here

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPrash.......View Question on Stackoverflow
Solution 1 - IphoneHobbes the TigeView Answer on Stackoverflow
Solution 2 - IphonePrakashView Answer on Stackoverflow
Solution 3 - IphoneChristian KienleView Answer on Stackoverflow
Solution 4 - IphoneLalit Kumar MauryaView Answer on Stackoverflow
Solution 5 - IphoneHobbes the TigeView Answer on Stackoverflow
Solution 6 - IphoneVarsheenView Answer on Stackoverflow
Solution 7 - IphoneAri BraginskyView Answer on Stackoverflow