字典键排序选项 - Alpha然后是数字

时间:2012-02-17 12:13:11

标签: ios cocoa-touch sorting nsmutabledictionary

所有

我想对这个可变字典的数组键进行排序,如下所示:A-Z 0-9但是它的回归排序为0-9 A-Z。我如何对它进行排序,使得alpha字符出现在数字之前?也许有一个内置方法可以做到这一点,还是应该创建一个扩展NSString的类别?

    NSArray *sKeysArray = [[listContent allKeys] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
    NSString *sectionKey = [sKeysArray objectAtIndex:section];
    NSArray *sectionValues = [listContent valueForKey:sectionKey];

2 个答案:

答案 0 :(得分:4)

可悲的是NSString中没有直接执行此操作的方法。我只想使用NSArray s sortedArrayUsingComparator:方法:

,而不是写一个类别
NSArray *sKeysArray = [[listContent ALlKeys] sortedArrayUsingComparator:^(id obj1, id obj2) {
// Code to compare obj1 and obj2 and return an NSComparisonResult here; return NSOrderedAscending if obj1 should come before obj2 
}];

为了进行每次比较,我会使用NSString的{​​{1}}传递– enumerateSubstringsInRange:options:usingBlock:作为选项(基本上枚举字符,除了实际上是一个“字母”的unicode字符序列组合)。当你比较两个字符时,使用类似于question的答案来检测obj1是一个数字,obj2是常规字母并返回NSStringEnumerationByComposedCharacterSequences,否则只需使用常规NSOrderedDescending

答案 1 :(得分:2)

就像@yuri所说,sortedArrayUsingComparator:应该提供基本功能。

这是一个简单的版本,在以字母字符开头的字符串开头(在NSCharacterSet的定义中)之后对以十进制数字开头的字符串进行排序,并将所有其他字符串组合保留为其默认排序顺序:

NSArray *arr = [NSArray arrayWithObjects:
                 @"ABC 09 GHJ", @"DEF23PO", @"123ABC", @"MCMLXV", @"[cocoa]", @"$2000", @"ERT", @"24seven", @"zero",
                @"Ångström", @"Übernacht",
                nil];

NSCharacterSet *digits    = [NSCharacterSet decimalDigitCharacterSet];
NSCharacterSet *alphanums = [NSCharacterSet alphanumericCharacterSet];

NSArray *sorted = [arr sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {

    if ( [obj1 isKindOfClass:[NSString class]] && [obj1 length] > 0
        && [obj2 isKindOfClass:[NSString class]] && [obj2 length] > 0 ) {

        unichar c1 = [obj1 characterAtIndex:0];
        unichar c2 = [obj2 characterAtIndex:0];

        if ( [digits characterIsMember:c1] && (![digits characterIsMember:c2] && [alphanums characterIsMember:c2]) ) {
            return NSOrderedDescending;
        }

        if ( [digits characterIsMember:c2] && (![digits characterIsMember:c1] && [alphanums characterIsMember:c1]) ) {
            return NSOrderedAscending;
        }
    }

    return [obj1 compare: obj2];
}];

NSLog(@"Sorted: %@", sorted);

警告:它不会正确处理由十进制数字组成的unicode字母作为第一个组件,但我会考虑这个病态案例直到有人能够启发我。