2014-11-24 2 views
-2

Я хочу отсортировать массив NSStrings по длине, но затем все строки, которые имеют одинаковую длину, будут отсортированы по алфавиту. Например, «кошка, шляпа, дзен, девять, скорость, рассказ, доступ, исчезают».Сортировка строк по алфавиту И по длине?

Как я могу это сделать? Я пытался найти NSSortDescriptors как час и никуда не пропал. Я не знаю, какие ключи использовать для сортировки NSStrings в алфавитном порядке или по длине. Я отсортировал их по алфавиту с помощью sortedArrayUsingSelector, но по ссылке комментария KevinTTrimm мне нужно использовать NSSortDescriptor для сортировки по двум метрикам, поэтому мне нужно знать ключи.

+2

Несомненно, вы должны были что-то совершить в этот час. Это помогло бы нам, если бы вы могли показать нам, как далеко вы добрались, и где вы застряли. –

+0

Возможный дубликат [Как установить вторичный ключ сортировки NSSortDescriptor?] (Http://stackoverflow.com/questions/8410637/how-to-establish-secondary-nssortdescriptor-sort-key) – KevinDTimm

+0

@ DavidRönnqvist Я застрял в понимании какие свойства (ключи) использовать с NSSortDescriptor для сортировки строк по алфавиту или по длине. Я видел ответ KevenDTrimm, но все примеры, которые я нашел, показывают только, как это сделать с произвольными объектами. Я не понял, как сортировать NSStrings, используя NSSortDescriptors, потому что я не знаю, какие свойства использовать. И теперь это просто забрасывается в забвение по какой-то реальной причине, так что это довольно обескураживающе. Не дай бог, опытные программисты iOS считают это тривиальным - автоматически глупый вопрос, DOWNVOTE. – Aerovistae

ответ

4

ТЛ; др: ключевые трактов вы ищете являются «длина» и «я» (или «описание» или «uppercaseString» в зависимости от того, как вы хотите сравнить)


как йо u можно увидеть в документации для NSSSortDescriptor, дескриптор сортировки создается «путем указания пути ключа к сравниваемому свойству». При сортировке строки их длиной свойство на NSString, что вы ищете length:

@property(readonly) NSUInteger length; 

Так как вы хотите, слова, чтобы быть длиннее и длиннее, что-то дескриптор должен быть восходящим, так что позже значения имеют на большую длину, чем предыдущее значение.

NSSortDescriptor *byLength = 
    [NSSortDescriptor sortDescriptorWithKey:@"length" ascending:YES]; 

Далее, чтобы отсортировать строку по алфавиту, то, что вы действительно хотите, это сравнить строку непосредственно с другой строкой. Есть несколько способов сделать это. Например, метод description в NSString (который может быть вызван с использованием KVC) документирован для возврата «Этот объект NSString», что означает сам объект. Это будет один из вариантов.

NSSortDescriptor *alphabeticallyAlternative1 = 
    [NSSortDescriptor sortDescriptorWithKey:@"description" ascending:YES]; 

Другие методы, которые вы можете вызвать более KVC являются, например, uppercaseString или lowercaseString. Используя любой из них в дескрипторе сортировки, вы получите нечувствительное к регистру сравнение (которое либо полезно для вас, либо оно не является).

// case-insensitive comparison 
NSSortDescriptor *alphabeticallyAlternative2 = 
    [NSSortDescriptor sortDescriptorWithKey:@"uppercaseString" ascending:YES]; 

Третий способ сравнения самой строки непосредственно с другой строкой, чтобы использовать ключ пути "self". Иногда вы увидите, что это используется в предикатах.

NSSortDescriptor *alphabeticallyAlternative3 = 
    [NSSortDescriptor sortDescriptorWithKey:@"self" ascending:YES]; 

Во всех 3 случаях дескриптор рода был сделан восходящим, так что письма, которые появляются позже в алфавите позже в массиве.


Какой бы вариант алфавитной сортировки, которые вы выбираете, так как вы хотите, чтобы отсортировать по длине первой вы бы передать дескриптор byLength первого и алфавитный дескриптора второго.

NSArray *sorted = 
    [someStrings sortedArrayUsingDescriptors:@[byLength, alphabetically]]; 
+0

Совершенно хорошо объясненный ответ с ключевыми элементами, которые мне нужны (имена клавиш, которые совсем не очевидны из документации, если вы новичок в Foundation) ... сразу после того, как я получил ее с помощью блока, как видно из мой ответ. Но ваш ответ, конечно, гораздо более краток. Спасибо. На втором взгляде они примерно равны по краткости, но это все еще то, что я изначально хотел. – Aerovistae

2

Я пытался выяснить NSSortDescriptors монетой часа

Зачем использовать NSSortDescriptors вообще? Я имею в виду, они приятные, но это намного проще, используя что-то вроде sortedArrayUsingComparator:, потому что вы можете просто написать свой собственный тест, говорящий, что считается больше, чем и то, что считается меньше.

+0

И вот пример из моей книги: http://www.apeth.com/iOSBook/ch03.html#_blocks – matt

+0

МОЙ БОГ, ПОЛЕЗНЫЙ ОТВЕТ! Остается надежда. Я пытаюсь найти четкое объяснение того, как работает «сравнение». Мне нужно настроить блок для сортировки по длине, а затем по алфавиту, если длины равны. Я имею в виду, я готов пойти с любым подходом, который работает - это просто вопрос, который мне удается понять, чтобы правильно изменить сначала. – Aerovistae

+0

Я отредактировал это для этого - 'NSArray * arr2 = [слова sortedArrayUsingComparator:^(NSString * s1, NSString * s2) { if ([s1 length]! = [S2 length]) { return [s1 compareBySize: s2 ]; } else return [s1 compare: s2]; }]; 'но' compareBySize', конечно, не настоящий селектор, поэтому я пытаюсь понять, как это должно быть написано. Было бы легко, если бы я мог просто использовать логические значения, но из * курса * должна быть эта вещь NSComparisonResult .... – Aerovistae

0

Наконец получил его:

NSArray* words2 = [words sortedArrayUsingComparator: ^(NSString* s1, NSString* s2) { 
    if([s1 length] != [s2 length]){ 
     NSNumber* s1length = [NSNumber numberWithInt:[s1 length]]; 
     NSNumber* s2length = [NSNumber numberWithInt:[s2 length]]; 
     return [s1length compare:s2length]; 
    } 
    else return [s1 compare:s2]; 
}]; 

Не знаю, почему они чувствовали булево было недостаточно, и добавил NSComparisonResult, но все ...

+0

Это не добавляет ничего полезного для моего ответа, плюс Stack Overflow - это не место для выхода. – matt

+0

Конечно, я удалил вентиляцию, но он добавляет к вашему ответу, что на самом деле показывает, что вам нужно. Мне нравятся полные примеры кода. – Aerovistae

+1

Ну, я никогда не собирался помогать, написав для вас свой код. :) Я также не могу сказать пользователям Stack Overflow, которые требуют такого рода вещей. Как учитель, моя задача - показать вам открытую дверь, а не провести вас через нее. – matt