I want to sort an array using NSSortDescriptor
Asked Answered
H

7

73

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

Houdan answered 4/4, 2011 at 18:37 Comment(0)
O
170

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]; 
Ottavia answered 4/4, 2011 at 18:49 Comment(5)
But still it does not sort it gives me first all capital and then lowercaseHoudan
Can you give some sample of the sort you want?Ottavia
Look at the image displays it gives me the unsorted output as if in this case "c" should comes first but Cancer comes at the first position. So please help me out in this case.Houdan
I had the same problem, but the given solution works fine in my case.Cornia
Perfect answer. "localizedCaseInsensitiveCompare" makes sure strings starting with foreign characters (eg the French e-acute) also appear sorted correctly in the list, and also copes with uppercase/lowercase nicely.Singlehanded
C
41

Just use NSSortDescriptor like I used and It worked fine.

   NSSortDescriptor * sortByRank = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES selector:@selector(caseInsensitiveCompare:)];
Caravaggio answered 15/2, 2013 at 3:49 Comment(0)
A
6

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."

Aniline answered 24/1, 2012 at 13:5 Comment(0)
I
4

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.

Ideography answered 3/9, 2012 at 4:8 Comment(0)
O
2

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
Ottavia answered 5/4, 2011 at 14:9 Comment(0)
P
2

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];
}
Par answered 9/2, 2012 at 11:13 Comment(0)
B
2

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.

Battologize answered 28/6, 2013 at 19:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.