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


375

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

Ответы:


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:)];

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]];

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];
    }
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.