Як сортувати NSArray в алфавітному порядку?


Відповіді:


725

Найпростіший підхід полягає у наданні селектора вибору ( документація Apple для деталей)

Ціль-С

sortedArray = [anArray sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];

Швидкий

let descriptor: NSSortDescriptor = NSSortDescriptor(key: "YourKey", ascending: true, selector: "localizedCaseInsensitiveCompare:")
let sortedResults: NSArray = temparray.sortedArrayUsingDescriptors([descriptor])

Apple пропонує кілька селекторів для алфавітного сортування:

  • compare:
  • caseInsensitiveCompare:
  • localizedCompare:
  • localizedCaseInsensitiveCompare:
  • localizedStandardCompare:

Швидкий

var students = ["Kofi", "Abena", "Peter", "Kweku", "Akosua"]
students.sort()
print(students)
// Prints "["Abena", "Akosua", "Kofi", "Kweku", "Peter"]"

Довідково


5
Посилання на документацію застаріло, зразок коду насправді недостатньо, щоб фактично сортувати масив. localizedCaseInsensitiveCompare: потрібно якось визначити.
— М. Райан

34
Я оновив посилання. Дякуємо, що вказали на це. localizedCaseInsensitiveCompare: це метод NSString і повинен бути достатнім для сортування масиву рядків.
— Томас Зоечлінг

1
І це можна легко застосувати до масиву, що містить будь-які власні об’єкти (не лише NSString). Вам просто потрібно переконатися, що всі об'єкти у вашому масиві реалізували повідомлення, яке вказує селектор. Тоді всередині цього повідомлення ви просто викликаєте порівняння NSString для властивостей вашого об'єкта, які ви хочете порівняти.
— lgdev

Такі прості речі не повинні бути такими складними.
— Дмитро

276

Інші відповіді, надані тут, згадують, використовуючи @selector(localizedCaseInsensitiveCompare:) Це чудово підходить для масиву NSString, однак якщо ви хочете поширити це на інший тип об’єктів і сортувати ці об’єкти відповідно до властивості 'name', вам слід зробити це замість цього:

NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];
sortedArray=[anArray sortedArrayUsingDescriptors:@[sort]];

Ваші об’єкти будуть сортовані відповідно до властивості імені цих об'єктів.

Якщо ви хочете, щоб сортування було нечутливим до регістру, вам потрібно встановити дескриптор таким чином

NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES selector:@selector(caseInsensitiveCompare:)];

14
+1, Дякую Смішно, це випадки частішого використання, ніж прийнята відповідь.
— Vinay W

4
це сортує перші великі літери, а потім малі літери
— HarshIT

+1, Дескриптор сортування разом із селектором - це саме те, що я хотів, і жодної іншої відповіді на це не було. Велике спасибі людині
— Ганеш Сомані

1
Я отримую помилку, коли намагаюся таким чином сортувати масив рядків, оскільки nameце не є дійсним ключем. Який ключ я використовую для сортування рядків за алфавітом за допомогою NSSortDescriptor?
— тимчасове_користувач

27

Більш потужний спосіб сортування списку NSString для використання таких речей, як NSNumericSearch:

NSArray *sortedArrayOfString = [arrayOfString sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
            return [(NSString *)obj1 compare:(NSString *)obj2 options:NSNumericSearch];
        }];

У поєднанні з SortDescriptor це дало б щось на кшталт:

NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES comparator:^NSComparisonResult(id obj1, id obj2) {
        return [(NSString *)obj1 compare:(NSString *)obj2 options:NSNumericSearch];
    }];
NSArray *sortedArray = [anArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:sort]];

10

Використовуйте код нижче для сортування в алфавітному порядку:

    NSArray *unsortedStrings = @[@"Verdana", @"MS San Serif", @"Times New Roman",@"Chalkduster",@"Impact"];

    NSArray *sortedStrings =
    [unsortedStrings sortedArrayUsingSelector:@selector(compare:)];

    NSLog(@"Unsorted Array : %@",unsortedStrings);        
    NSLog(@"Sorted Array : %@",sortedStrings);

Нижче наведено журнал консолі:

2015-04-02 16:17:50.614 ToDoList[2133:100512] Unsorted Array : (
    Verdana,
    "MS San Serif",
    "Times New Roman",
    Chalkduster,
    Impact
)

2015-04-02 16:17:50.615 ToDoList[2133:100512] Sorted Array : (
    Chalkduster,
    Impact,
    "MS San Serif",
    "Times New Roman",
    Verdana
)

10

Ще один простий метод сортування масиву рядків складається з використання descriptionвластивості NSString таким чином:

NSSortDescriptor *valueDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"description" ascending:YES];
arrayOfSortedStrings = [arrayOfNotSortedStrings sortedArrayUsingDescriptors:@[valueDescriptor]];

1
Це здається трохи марним; немає причин сортувати рядки таким чином (і, мабуть, для цього є хіт продуктивності), а для інших об'єктів властивість його опису рідко корисна для цілей сортування.
— ма

3

Це вже має гарні відповіді на більшість цілей, але я додам ще конкретнішу.

Англійською мовою зазвичай, коли ми буквені, ми ігноруємо слово "the" на початку фрази. Тож "Сполучені Штати" будуть впорядковані під "U", а не "T".

Це робить це для вас.

Напевно, найкраще було б розмістити їх у категоріях.

// Sort an array of NSStrings alphabetically, ignoring the word "the" at the beginning of a string.

-(NSArray*) sortArrayAlphabeticallyIgnoringThes:(NSArray*) unsortedArray {

    NSArray * sortedArray = [unsortedArray sortedArrayUsingComparator:^NSComparisonResult(NSString* a, NSString* b) {

        //find the strings that will actually be compared for alphabetical ordering
        NSString* firstStringToCompare = [self stringByRemovingPrecedingThe:a];
        NSString* secondStringToCompare = [self stringByRemovingPrecedingThe:b];

        return [firstStringToCompare compare:secondStringToCompare];
    }];
    return sortedArray;
}

// Remove "the"s, also removes preceding white spaces that are left as a result. Assumes no preceding whitespaces to start with. nb: Trailing white spaces will be deleted too.

-(NSString*) stringByRemovingPrecedingThe:(NSString*) originalString {
    NSString* result;
    if ([[originalString substringToIndex:3].lowercaseString isEqualToString:@"the"]) {
        result = [[originalString substringFromIndex:3] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
    }
    else {
        result = originalString;
    }
    return result;
}

Я тільки що подивився на це років пізніше, і зрозумів, що він повинен включати "а" і "а". Це слід легко додати.
— нарко

1
-(IBAction)SegmentbtnCLK:(id)sender
{ [self sortArryofDictionary];
    [self.objtable reloadData];}
-(void)sortArryofDictionary
{ NSSortDescriptor *sorter;
    switch (sortcontrol.selectedSegmentIndex)
    {case 0:
            sorter=[[NSSortDescriptor alloc]initWithKey:@"Name" ascending:YES];
            break;
        case 1:
            sorter=[[NSSortDescriptor alloc]initWithKey:@"Age" ascending:YES];
            default:
            break; }
    NSArray *sortdiscriptor=[[NSArray alloc]initWithObjects:sorter, nil];
    [arr sortUsingDescriptors:sortdiscriptor];
    }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.