Как отсортировать NSArray по алфавиту?

375

Как я могу отсортировать массив, заполненный [UIFont familyNames]в алфавитном порядке?

DotSlashSlash
источник

Ответы:

725

Самый простой подход заключается в предоставлении селектора сортировки ( подробности в документации Apple )

Objective-C

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:)];
JP Hribovsek
источник
14
+1, спасибо. Забавно, что это более распространенный вариант использования, чем принятый ответ.
Vinay W
4
сначала сортируются заглавные буквы, а затем строчные
HarshIT
+1, дескриптор сортировки вместе с селектором - именно то, что я хотел, и никакой другой ответ не имел этого. Большое спасибо мужик
Ганеш Сомани
1
Я получаю сообщение об ошибке, когда пытаюсь отсортировать массив строк таким образом, потому что nameэто недопустимый ключ. Какой ключ я использую для сортировки строк в алфавитном порядке с помощью NSSortDescriptor?
temporary_user_name
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]];
Lisarien
источник
1
Это кажется немного бесполезным; нет смысла сортировать строки таким образом (и, вероятно, при этом наблюдается снижение производительности), а для других объектов его свойство description редко используется для целей сортировки.
март
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];
    }
Deepa
источник