2012-03-12 131 views
28

我已经创建了一个排序描述符来排序来自我的服务器的plist响应。这适用于具有高达9的值的排序键。对于超过10个项目,我看到突变结果,排序键按顺序排列= 1,10,11,2,3,4,5,6,7,8,90。对NSString值进行排序,就好像NSInteger使用NSSortDescriptor一样

NSSortDescriptor *aSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"sort" ascending:YES]; 
self.myList = [NSMutableArray arrayWithArray:[unsortedList sortedArrayUsingDescriptors:[NSArray arrayWithObject:aSortDescriptor]]]; 

如何使它按照1,2,3,4,5,6,7,8,9,10,11的正确顺序排列?

回答

44

您可以通过创建时实现自定义比较块你NSSortDescriptor做到这一点:

NSSortDescriptor *aSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"sort" ascending:YES comparator:^(id obj1, id obj2) { 

    if ([obj1 integerValue] > [obj2 integerValue]) { 
     return (NSComparisonResult)NSOrderedDescending; 
    } 
    if ([obj1 integerValue] < [obj2 integerValue]) { 
     return (NSComparisonResult)NSOrderedAscending; 
    } 
    return (NSComparisonResult)NSOrderedSame; 
}]; 
self.myList = [NSMutableArray arrayWithArray:[unsortedList sortedArrayUsingDescriptors:[NSArray arrayWithObject:aSortDescriptor]]]; 

看到苹果文档here

+1

请注意,此解决方案将无法与CoreData fetchRequests工作,因为它不接受基于块的描述符。 – OlDor 2016-01-11 03:46:39

7
NSMutableArray *list = [NSMutableArray arrayWithObjects:@"11",@"2",@"3",@"1", nil]; 
[list sortUsingComparator:^NSComparisonResult(id obj1, id obj2) { 
    NSInteger firstInteger = [obj1 integerValue]; 
    NSInteger secondInteger = [obj2 integerValue]; 
    if(firstInteger > secondInteger) return NSOrderedDescending; 
    if(firstInteger == secondInteger) return NSOrderedSame; 
    return NSOrderedAscending; // edited 
}]; 

并未作出任何保证性能

+0

请注意,此解决方案不适用于CoreData fetchRequests,因为它不接受基于块的描述符。 – OlDor 2016-01-11 03:47:23

11

你需要你的字符串与NSNumericSearch选项进行比较:

串内张

NSNumericSearch
的数用比较了数字值,即,Name2.txt < Name7.txt < Name25.txt

这需要调用compare:options:方法进行比较。

为了做到这一点,你的排序描述符可以使用NSComparator Block

[NSSortDescriptor sortDescriptorWithKey:@"self" 
           ascending:YES 
          comparator:^(NSString * string1, NSString * string2){ 
              return [string1 compare:string2 
                  options:NSNumericSearch]; 
}]; 

,或者更确切地说,你可以跳过排序描述符和简单sort the array directly,使用相同的块:

[unsortedList sortedArrayUsingComparator:^NSComparisonResult (NSString * string1, NSString * string2){ 
    return [string1 compare:string2 
        options:NSNumericSearch]; 
}]; 
+0

小增加:为什么要转换成'NSString'?您可以直接传递'NSString'而不是'id',这样可以更容易阅读。 :-) – 2013-03-08 13:58:16

+0

这是一个很棒的点,@Blauesocke;谢谢! – 2013-03-08 17:52:39

+0

请注意,此解决方案不适用于CoreData fetchRequests,因为它不接受基于块的描述符。 – OlDor 2016-01-11 03:47:14

38

[list sortUsingSelector:@selector(localizedStandardCompare:)];会以“人”的方式对列表进行排序(所以“11”最后会出现,而不是“1”和“2”之间)。但是如果你真的想把这些字符串当作数字来对待,你应该先让它们成为数字!

+1

这种方式更清洁。 – pir800 2012-12-05 21:28:56

+0

完美!其他解决方案对我来说不起作用,因为CoreData不接受基于块的sortDescriptors。但是这个工作。 – OlDor 2016-01-11 03:45:33

+0

对我来说最好的解决方案;) – 2017-02-12 09:27:58

16
NSSortDescriptor *aSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"sort.intValue" ascending:YES]; 
self.myList = [NSMutableArray arrayWithArray:[unsortedList sortedArrayUsingDescriptors:[NSArray arrayWithObject:aSortDescriptor]]]; 

根据整数的值进行排序。

+0

完美的简单! – DonnaLea 2014-07-17 06:17:26

+0

没有工作。我得到'0 1 10 11 12 ... 2 3 4'而不是'0 1 2 3 4 ... 10 11 12' – OlDor 2016-01-11 03:21:21

+0

最简单的答案。很好地处理整数值 – 2016-02-24 09:57:29

0

以上所有方法都需要很好的基础知识来实施;但对于新手我建议最简单的方法 - 使用[NSSortDescriptor sortDescriptorWithKey使用本地块的方法

NSArray* sortedArr =[fetchResults sortedArrayUsingComparator:^NSComparisonResult(id a, id b) { 

    int aValue = [[a valueForKey:@"subgroupId"] intValue]; 
    int bValue = [[b valueForKey:@"subgroupId"] intValue]; 

    return aValue > bValue; 
}]; 
0

输入

{ 
    "seats": [{ 
     "seatNumber": "1" 
    }, { 
     "seatNumber": "10" 
    }, { 
     "seatNumber": "2" 
    }] 
} 

排序:@ “seatNumber” 升:是选择:@selector(localizedStandardCompare :)]。关键是使用localizedStandardCompare。这会解决你的问题。

NSArray *seats = [self.seats sortedArrayUsingDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"seatNumber" ascending:YES selector:@selector(localizedStandardCompare:)]]]; 

输出

{ 
    "seats": [{ 
     "seatNumber": "1" 
    }, { 
     "seatNumber": "2" 
    }, { 
     "seatNumber": "10" 
    }] 
} 

文档: https://developer.apple.com/documentation/foundation/nsstring/1409742-localizedstandardcompare

+0

你不应该只用代码回答,而是尝试给出一个描述/解释它的作用,它是如何解决问题的,等等。 – 2017-10-13 23:56:40

相关问题