我有一个对象数组,我需要按照“标题”键排序。它目前正在工作,虽然它使用的是ASCII排序而不是自然排序。标题是文件名,所以它们看起来像这样:
file1的
文件2
文件3
...
file10
FILE11
file12
我正如你所料的那样:
file1的
file10
FILE11
file12
文件2
文件3
......
有没有人知道NSArray排序功能是否内置了一种方法来获得这种自然排序而不是字母排序?我找到了一些通用算法,但我希望内置一些东西......
答案 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]];