Сортировать NSArray из NSStrings, как Addressbook на Iphone сортировать - PullRequest
9 голосов
/ 27 июля 2011

У меня есть массив строк (имен)

и я хотел бы отсортировать их так, как их сортирует адресная книга на iphone

  • Например: éli -> под E
  • Например: Али -> под A
  • Например: 4li -> под #

есть предложения?

Ответы [ 2 ]

11 голосов
/ 27 июля 2011

Вы должны выполнить диакритическое нечувствительное сравнение со строками.NSString имеет метод compare:options: с опцией NSDiacriticInsensitiveSearch.

NSArray *array = [NSArray arrayWithObjects:@"éli", @"bob", @"earl", @"allen", @"àli", @"aaron", nil];

NSArray *sorted = [array sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
    return [(NSString*)obj1 compare:obj2 options:NSDiacriticInsensitiveSearch|NSCaseInsensitiveSearch];
}];

Редактировать:

Вот полныйпример, который будет разделять результаты на основе первого символа, нечувствительного к диакритике.Я вставил в словарь, чтобы вы могли самостоятельно отслеживать отсортированные клавиши для правильного отображения.

NSArray *array = [NSArray arrayWithObjects:@"éli", @"bob", @"earl", @"allen", @"àli", nil];

NSArray *sorted = [array sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
    return [(NSString*)obj1 compare:obj2 options:NSDiacriticInsensitiveSearch|NSCaseInsensitiveSearch];
}];

NSMutableDictionary *sectioned = [NSMutableDictionary dictionary];
NSString *firstChar = nil;

for(NSString *str in sorted)
{
    //Ignore empty strings
    if(![str length])continue;

    NSMutableArray *names = nil;

    //Compare the first character using diacritic insensitive search
    if([str compare:firstChar options:NSDiacriticInsensitiveSearch|NSCaseInsensitiveSearch range:NSMakeRange(0, 1)] == NSOrderedSame)
    {
        names = [sectioned objectForKey:firstChar];
    }
    else
    {
        //decomposedStringWithCanonicalMapping is where the magic happens
        //(it removes the accent mark)
        firstChar = [[str decomposedStringWithCanonicalMapping] substringToIndex:1];
        names = [NSMutableArray array];
        [sectioned setObject:names forKey:firstChar];
    }

    [names addObject:str];
}

NSLog(@"sorted: %@", sorted);
//This is sectioned like the address app
NSLog(@"sectioned: %@", sectioned);
1 голос
/ 27 июля 2011

все лежит в методе compare:, который вы будете использовать в качестве селектора метода сортировки и, что более важно, в опции NSDiacriticInsensitiveSearch.

[[yourArray] sortedArrayUsingSelector:@selector(compareTheAddressBookWay:)];

Теперь вам нужно добавить метод compareTheAddressBookWay:в категории

@implementation NSString (YourCategory)

- (NSComparisonResult) compareTheAddressBookWay:(NSString*)iString
{
    return [self compare:iString 
                 options:NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch 
                   range:NSRangeFromString(self)
}

@end

!! Важно !!:

Использование sortedArrayUsingSelector: будет совместимо с iOS до 2.0
при использовании sortedArrayUsingComparator: ТОЛЬКО будет работать для iOS 4 и выше.

...