简体   繁体   English

使用NSSortDescriptor对NSString值进行排序,就好像NSInteger

[英]Sorting NSString values as if NSInteger using NSSortDescriptor

I have created a sort descriptor to sort a plist response coming from my server. 我创建了一个排序描述符,对来自服务器的plist响应进行排序。 This works well with sort key having values upto 9. With more than 10 items I see abrupt results with sort key arranged in the order = 1, 10, 11, 2, 3, 4, 5, 6, 7, 8, 9 这对于值最高为9的排序键效果很好。在超过10个项目中,我看到了按顺序排列排序键= 1、10、11、2、3、4、5、6、7、8、9的突然结果

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

How to make it arrange in the correct order of 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11? 如何以正确的顺序排列1、2、3、4、5、6、7、8、9、10、11?

You can do this by implementing a custom comparator block when creating your NSSortDescriptor : 您可以通过在创建NSSortDescriptor时实现自定义比较器块来实现此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]]];

See Apple documentation here 在此处查看Apple文档

[list sortUsingSelector:@selector(localizedStandardCompare:)]; will sort the list in a "human" way (so "11" will come last, not between "1" and "2"). 将以“人工”方式对列表进行排序(因此,“ 11”将排在最后,而不是在“ 1”和“ 2”之间)。 But if you really do want to treat these strings as numbers, you should make them number first! 但是,如果您确实希望将这些字符串视为数字,则应首先使其成为数字!

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

Sort based on the value of the integer. 根据整数值排序。

You need your strings to be compared with the NSNumericSearch option: 您需要将您的字符串与NSNumericSearch选项进行比较:

NSNumericSearch
Numbers within strings are compared using numeric value, that is, Name2.txt < Name7.txt < Name25.txt . 使用数字值比较字符串中的数字,即Name2.txt < Name7.txt < Name25.txt

which requires the compare:options: method to be called for the comparison. 这需要调用compare:options:方法进行比较。

In order to do that, your sort descriptor can use an NSComparator Block : 为此,您的排序描述符可以使用NSComparator

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

Or, indeed, you can skip the sort descriptor and simply sort the array directly , using the same Block: 或者,实际上,您可以跳过排序描述符,而直接使用相同的Block 直接对数组进行排序

[unsortedList sortedArrayUsingComparator:^NSComparisonResult (NSString * string1, NSString * string2){
    return [string1 compare:string2
                    options:NSNumericSearch];
 }];
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
}];

No guarantees about performance 无法保证性能

All the above methods need good knowledge of basics to implement; 以上所有方法都需要具备良好的基础知识才能实施; but for the newbies I suggest the simplest way – to use the native block method 但对于新手,我建议最简单的方法–使用本机阻止方法

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

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

    return aValue > bValue;
}];

input 输入

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

sort using [NSSortDescriptor sortDescriptorWithKey:@"seatNumber" ascending:YES selector:@selector(localizedStandardCompare:)]]. 使用[NSSortDescriptor sortDescriptorWithKey:@“ seatNumber”升序:是选择器:@selector(localizedStandardCompare :)]进行排序。 The key is to use localizedStandardCompare. 关键是要使用localizedStandardCompare。 This will solve you problem. 这将解决您的问题。

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

output 输出

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM