关于排序:iOS-SortDescriptor,其中内容既是字母又是数字

iOS - SortDescriptor where content is both alpha and numeric

我见过很多关于如何对1,10,2,3等进行排序的问题。

我有一些以以下形式导入的Json数据:@"arrived"@"boarding"@"1"@"2"@"3"等。

我目前只有一个不区分大小写的排序:

1
sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"time" ascending:YES selector:@selector(caseInsensitiveCompare:)];

在上面需要的形式中,这会首先对数字进行排序,然后对单词进行排序。

我必须执行哪些选择? 谢谢


这个冗长的比较器可以解决这个问题:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
NSArray *testArray = @[@"3", @"boarding", @"2", @"arrived", @"1"];

NSArray *sortedArray = [testArray sortedArrayUsingComparator:^NSComparisonResult(NSString *obj1, NSString *obj2) {
    NSInteger firstInteger = 0;
    BOOL isInteger1 = [[NSScanner scannerWithString:obj1] scanInteger:&firstInteger];

    NSInteger secondInteger = 0;
    BOOL isInteger2 = [[NSScanner scannerWithString:obj2] scanInteger:&secondInteger];

    if (isInteger1 && isInteger2) {
        // Normal integer comparison
        if (firstInteger > secondInteger) {
            return NSOrderedDescending;
        }
        else if (secondInteger > firstInteger) {
            return NSOrderedAscending;
        }
        else {
            return NSOrderedSame;
        }
    }
    else if (isInteger1) {
        return NSOrderedDescending;
    }
    else if (isInteger2) {
        return NSOrderedAscending;
    }
    else {
        return [obj1 compare:obj2 options:NSCaseInsensitiveSearch];
    }
}];

编辑

样本输出:

1
2
3
4
5
6
7
Printing description of sortedArray:
<__NSArrayI 0x7ffacaa26da0>(
arrived,
boarding,
1,
2,
3


试试这个

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    NSComparator compare=^(id obj1, id obj2) {
    NSString *s1 = [obj1 substringToIndex:1];
    NSString *s2 = [obj2 substringToIndex:1];

    NSRange r1 = [s1 rangeOfCharacterFromSet:[NSCharacterSet decimalDigitCharacterSet]];
    NSRange r2 = [s2 rangeOfCharacterFromSet:[NSCharacterSet decimalDigitCharacterSet]];
    if (r1.location == r2.location ) { // either both start with a number or both with a letter
        return [obj1 compare:obj2 options:NSDiacriticInsensitiveSearch|NSCaseInsensitiveSearch];
    } else {  // one starts wit a letter, the other with a number
        if ([s1 rangeOfCharacterFromSet:[NSCharacterSet decimalDigitCharacterSet]].location == NSNotFound) {
            return NSOrderedAscending;
        }
        return NSOrderedDescending;
    }
};

NSSortDescriptor *desc=[[NSSortDescriptor alloc]initWithKey:@"time" ascending:YES comparator:compare];

originalArray =  [originalArray sortedArrayUsingDescriptors:@[desc]];

可能会帮助您。