Menu
Coddy logo textTech

sorted(by:)

Часть раздела Логика и управление потоком путешествия по Swift на Coddy — урок 30 из 56.

Вы использовали .sorted() для массивов значений Comparable, таких как числа или строки. Если вы хотите выполнить сортировку по другому критерию, передайте замыкание, которое принимает два элемента и возвращает true, если первый элемент должен стоять перед вторым.

let words = ["banana", "hi", "hello"]
let byLength = words.sorted { $0.count < $1.count }
print(byLength)              // ["hi", "hello", "banana"]

Для сортировки по убыванию измените условие сравнения:

let down = words.sorted { $0.count > $1.count }
print(down)                  // ["banana", "hello", "hi"]

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

min(by:) и max(by:) работают так же, но возвращают один опциональный элемент, а не отсортированную копию.

challenge icon

Задание

Средне

Прочитайте одну строку ввода: список пар name:age, разделенных запятыми.

Выведите три строки:

  1. Имена, отсортированные по возрасту по возрастанию, объединенные через ,. При совпадении возраста сортируйте имена по алфавиту.
  2. Имя самого старого человека (используйте max(by:)). При совпадении выигрывает тот, кто встретился первым.
  3. Имя самого молодого человека (используйте min(by:)). При совпадении выигрывает тот, кто встретился первым.

Для входных данных alice:30,bob:22,cara:30,dan:18 вывод будет следующим:

dan,bob,alice,cara
alice
dan

Шпаргалка

Используйте .sorted { } с пользовательским замыканием для сортировки по любому производному значению. Замыкание принимает два элемента и возвращает true, если первый должен стоять перед вторым:

let words = ["banana", "hi", "hello"]
let byLength = words.sorted { $0.count < $1.count }
// ["hi", "hello", "banana"]

Для сортировки по убыванию замените оператор:

let down = words.sorted { $0.count > $1.count }
// ["banana", "hello", "hi"]

min(by:) и max(by:) используют ту же сигнатуру замыкания, но возвращают один опциональный элемент:

let longest = words.max(by: { $0.count < $1.count })  // "banana"
let shortest = words.min(by: { $0.count < $1.count }) // "hi"

Попробуйте сами

let people = readLine()!.components(separatedBy: ",").map { pair -> (String, Int) in
    let parts = pair.components(separatedBy: ":")
    return (parts[0], Int(parts[1])!)
}

// TODO: сортировать по возрасту по возрастанию (при совпадении — по имени); max(by:) для самого старшего; min(by:) для самого младшего
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Логика и управление потоком