如何在NSArray上进行自然排序?

时间:2010-05-17 02:12:48

标签: iphone objective-c cocoa sorting

我有一个对象数组,我需要按照“标题”键排序。它目前正在工作,虽然它使用的是ASCII排序而不是自然排序。标题是文件名,所以它们看起来像这样:

file1的
文件2
文件3
...
file10
FILE11
file12

我正如你所料的那样:

file1的
file10
FILE11
file12
文件2
文件3
......

有没有人知道NSArray排序功能是否内置了一种方法来获得这种自然排序而不是字母排序?我找到了一些通用算法,但我希望内置一些东西......

5 个答案:

答案 0 :(得分:53)

NSString可以compared使用NSNumericSearch比较选项。

一个版本:

NSInteger sort(Obj* a, Obj* b, void*) {
    return [[a title] compare:[b title] options:NSNumericSearch];
}

result = [array sortedArrayUsingFunction:&sort context:nil];

或者更通用一点:

NSInteger sort(id a, id b, void* p) {
    return [[a valueForKey:(NSString*)p] 
            compare:[b valueForKey:(NSString*)p]
            options:NSNumericSearch];
}

result = [array sortedArrayUsingFunction:&sort context:@"title"]

或使用块:

result = [array sortedArrayUsingComparator:^(Obj* a, Obj* b) { 
    return [[a title] compare:[b title] options:NSNumericSearch]; 
}];

答案 1 :(得分:24)

那些尝试在Mac OS X 10.6及更高版本以及iOS 4及更高版本上复制Finder排序行为的人可以使用localizedStandardCompare: 作为比较器选择器。

在早期版本的Mac OS X和/或iOS上具有相同目标的用户应使用the solution described in the String Programming Guide

答案 2 :(得分:4)

根据@ PeterHosey的回答,如果您正在处理一组字符串对象:

简短的答案:

NSArray *orderedTitles = [unorderedTitles sortedArrayUsingSelector:@selector(localizedStandardCompare:)];

完整示例:

NSArray *unorderedTitles = @[
    @"file12",
    @"file1",
    @"file10",
    @"file3",
    @"file2",
    @"file11"
];

NSArray *orderedTitles = [unorderedTitles sortedArrayUsingSelector:@selector(localizedStandardCompare:)];
NSLog(@"orderedTitles = %@", orderedTitles);
/*
orderedTitles = (
    file1,
    file2,
    file3,
    file10,
    file11,
    file12
)
*/

答案 3 :(得分:0)

这适用于iOS

NSString *name0 = @"winter";
NSString *name1 = @"summer";
CFComparisonResult result = CFStringCompareWithOptions(
    (CFStringRef) name0,
    (CFStringRef) name1,
    CFRangeMake (0, CFStringGetLength((CFStringRef) name0)),
    kCFCompareCaseInsensitive | kCFCompareLocalized | kCFCompareNumerically
);

答案 4 :(得分:0)

您还可以通过以下方式进行排序:

NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"title" ascending:YES selector:@selector(localizedStandardCompare:)];
NSArray *sortedItems = [unsortedItems sortedArrayUsingDescriptors:@[sortDescriptor]];