Подтвердить что ты не робот

Сортировка значений NSString как NSInteger с использованием NSSortDescriptor

Я создал дескриптор сортировки для сортировки ответчика plist, исходящего с моего сервера. Это хорошо работает с ключом сортировки, имеющим значения до 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]]];

Как сделать его упорядоченным в порядке 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11?

4b9b3361

Ответ 1

Это можно сделать, реализовав специальный блок-компаратор при создании 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]]];

См. документацию Apple здесь

Ответ 2

[list sortUsingSelector:@selector(localizedStandardCompare:)]; сортирует список по-человечески (так что "11" будет последним, а не между "1" и "2" ). Но если вы действительно хотите рассматривать эти строки как числа, вы должны сделать их номера первыми!

Ответ 3

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

Сортировка, основанная на значении целого числа.

Ответ 4

Вам нужно, чтобы ваши строки сравнивались с опцией NSNumericSearch:

NSNumericSearch
Числа внутри строк сравниваются с помощью числового значения, то есть Name2.txt < Name7.txt < Name25.txt.

для которого требуется метод compare:options:.

Для этого ваш дескриптор sort может использовать NSComparator Block:

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

Или, действительно, вы можете пропустить дескриптор сортировки и просто сортировать массив напрямую, используя тот же блок:

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

Ответ 5

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
}];

Нет гарантий относительно производительности

Ответ 6

Все вышеперечисленные методы нуждаются в хорошем знании основ для реализации; но для новичков я предлагаю самый простой способ - использовать метод нативного блока

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

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

    return aValue > bValue;
}];

Ответ 7

вход

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

сортировать с помощью [NSSortDescriptor sortDescriptorWithKey: @ "seatNumber" по возрастанию: селектор YES: @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