我想使用NSSortDescriptor对数组进行排序


72

我在排序数组wrt数据库时遇到问题:

NSSortDescriptor *sorter = [[NSSortDescriptor alloc] initWithKey:@"w" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject: sorter]; 

[mGlossaryArray sortUsingDescriptors:sortDescriptors]; 
[sorter release];

在数据库中,这里有一些首字母大写,并且由于该大写字母而无法显示正确的排序输出。在这里,我正在用rt“ w”排序一个数组,这是我数据库中的表列。在这里,我附上了输出的屏幕截图,该屏幕截图显示“ Cancer”比“ c”排在首位,但这是不正确的,因为大写单词没有按字母顺序排序。

例如。如果有小写的“ able”和小写的“ aCid”,那么它将先显示aCid,然后才有能力,并且还有一种情况,如果第一个字母为大写,则首先显示,例如“ Able”和“ a”。此处首先显示Able。在此处输入图片说明

Answers:


168

在这里看看: 创建和使用排序描述符

您可以比较不区分大小写。

NSSortDescriptor *sorter = [[[NSSortDescriptor alloc]
          initWithKey:@"w"
          ascending:YES
          selector:@selector(localizedCaseInsensitiveCompare:)] autorelease];
NSArray *sortDescriptors = [NSArray arrayWithObject: sorter];
[mGlossaryArray sortUsingDescriptors:sortDescriptors]; 

但是它仍然不能排序,它给了我全部的资本,然后是小写的
Prash .......

您可以提供所需种类的样品吗?
霍布斯巨虎

查看显示的图像,它给了我未分类的输出,好像在这种情况下“ c”应排在第一位,而Cancer在第一位。因此,在这种情况下,请帮助我。
Prash .......

我遇到了同样的问题,但是给定的解决方案在我的情况下效果很好。
Ben Groot 2012年

2
完美的答案。“ localizedCaseInsensitiveCompare”确保以外国字符开头的字符串(例如,法语e-acute)也可以在列表中正确排序,并且还可以很好地处理大写/小写字母。
Mike Gledhill

39

就像我以前使用NSSortDescriptor一样,它工作得很好。

   NSSortDescriptor * sortByRank = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES selector:@selector(caseInsensitiveCompare:)];

5

我可以建议使用-localizedStandardCompare:(NSString)吗?

“只要在适合于类似Finder的排序的列表和表中显示文件名或其他字符串,就应使用此方法。此方法的确切排序行为在不同的语言环境下会有所不同,并且在以后的版本中可能会更改。”


3

您可以使用它根据还包含小写字母的名称对数组进行排序:

NSSortDescriptor *sorter = [NSSortDescriptor sortDescriptorWithKey:@"w" ascending:YES selector:@selector(caseInsensitiveCompare:)];

NSArray *sortDescriptors = [NSArray arrayWithObject:sorter]; 

[mGlossaryArray sortUsingDescriptors:sortDescriptors];

此代码对我来说可以按字母顺序对名称进行排序,该字母也具有较小的字符,例如rocky,Ajay,john,Bob等。


2

我认为这将为您解决问题。它的文档在这里: 字符串编程指南

添加苹果编写的这个小功能。

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];
}

确保将函数定义复制到标头中,否则在排序数组上会出现编译错误。

对于排序数组,请使用以下方法:

[mGlossaryArray sortedArrayUsingFunction:finderSortWithLocale context:[NSLocale currentLocale]];

您的结果将如下所示:

  • C
  • 咖啡店
  • 癌症
  • 中文
  • 基督教
  • 圣诞
  • 可乐

2

这段代码对我来说很好用。

- (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];
}

2

Apple的使用区域设置方法的finder排序的另一种形式是使用比较器块,如果您在ARC环境中并且不想处理桥接类型转换,则很有用:

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]];

我也建议将当前语言环境存储在局部变量中,以提高效率。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.