Як сортувати 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.