Простой способ поставить пустые строки в конце сортировки с помощью NSSortDescriptor? - PullRequest
1 голос
/ 17 марта 2012

Я использую NSSortDescriptor для сортировки NSArray из NSDictionary предметов.Прекрасно работает, как раз то, что мне нужно ... за исключением того, что я хотел бы, чтобы элементы словаря с пустыми значениями для моего ключа сортировки отображались в конце отсортированного списка.Есть ли способ легко это сделать?Или мне придется создать некоторые пользовательские функции сортировки?И нет, я не хочу просто устанавливать его в порядок DESC ... Я бы хотел, чтобы отсортированные результаты выглядели как A, A, B, B, C, пробелы, пробелы.

Ответы [ 3 ]

2 голосов
/ 17 марта 2012

Понял это после просмотра другого примера с использованием пользовательского сравнения.Вот код, с которым я закончил:

@interface NSString (CustomStatusCompare)
- (NSComparisonResult)customStatusCompare:(NSString*)other;
@end

@implementation NSString (CustomStatusCompare)
- (NSComparisonResult)customStatusCompare:(NSString*)other {
    NSAssert([other isKindOfClass:[NSString class]], @"Must be a NSString");
    if ([self isEqual:other]) {
        return NSOrderedSame;
    }
    else if ([self length] > 0 && [other length] > 0) {
        return [self localizedCaseInsensitiveCompare:other];        
    }
    else if ([self length] > 0 && [other length] == 0) {
        return NSOrderedAscending;
    }
    else {
        return NSOrderedDescending;
    } 
}
@end



NSSortDescriptor *serviceTypeDescriptor =
[[NSSortDescriptor alloc] initWithKey:@"Service"
                             ascending:YES
                             selector:@selector(localizedCaseInsensitiveCompare:)];

NSSortDescriptor *locationDescriptor = 
[[NSSortDescriptor alloc] initWithKey:@"Location"
                             ascending:YES
                             selector:@selector(customStatusCompare:)];  //using custom comparison here!

NSArray *descriptors = [NSArray arrayWithObjects:locationDescriptor, nameDescriptor, nil];        
self.navArray = [self.navArray sortedArrayUsingDescriptors:descriptors];

Таким образом, компаратор возвращает NSOrderedSame, если обе строки пусты ... вызывает функцию обычного сравнения, если обе строки не пусты ... если только одна строкапустой, он меняет нормальный порядок сравнения.Voila!

0 голосов
/ 17 марта 2012

Редактировать: я неправильно прочитал вопрос и подумал, что целью было поставить строки с начальными пробелами в порядке сортировки (что им и так следовало бы). Вы хотите что-то подобное, я думаю. Это полностью не проверено и не учитывает несколько пробелов. Я уверен, что есть более элегантный способ, но он должен выполнить свою работу.

NSArray *sortedArray = [array sortedArrayUsingComparator: ^(id obj1, id obj2) {
    NSString *str1 = (NSString *)obj1;
    NSString *str2 = (NSString *)obj2;

    BOOL str1HasSpace = [str1 hasPrefix:@" "];
    BOOL str2HasSpace = [str2 hasPrefix:@" "];

    if (str1HasSpace && !str2HasSpace) {
        return NSOrderedAscending;
    } else if (str2HasSpace && ! str1HasSpace) {
        return NSOrderedDescending;
    } else {
        return [[str1 stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] compare:[str2 stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]];
    }
}];
0 голосов
/ 17 марта 2012

Выполните сортировку, используя NSNumericSort вместо NSDiacriticInsensitive или NSCaseInsensitive.Поскольку пробел в коде ascii составляет, вероятно, 256, он будет отправлен в конец списка.

...