В каких сценариях массив (Array) предпочтительнее множества (Set) в Swift?

«В каких сценариях массив (Array) предпочтительнее множества (Set) в Swift?» — вопрос из категории Алгоритмы и структуры данных, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Array следует выбирать над Set, когда критически важны следующие свойства:

  1. Сохранение порядка элементов: Лента постов, история действий, плейлист, очередь задач.
  2. Наличие дубликатов: Список логов, результаты измерений, где одно значение может встречаться多次.
  3. Доступ по целочисленному индексу: Необходимость получить, вставить или удалить элемент в конкретной позиции.
  4. Последовательная итерация в предсказуемом порядке: Обработка элементов в том же порядке, в котором они были добавлены.

Ключевое преимущество Array — детерминированный порядок и индексный доступ за O(1).

Практические примеры:

// Сценарий 1: Отображение отсортированного списка
// Array сохраняет порядок, заданный сортировкой.
var rankedPlayers: [String] = ["Alice", "Bob", "Charlie"]
rankedPlayers.sort(by: >) // Теперь: ["Charlie", "Bob", "Alice"]
print("Победитель: (rankedPlayers.first!)") // Детерминированный результат

// Сценарий 2: Работа с индексами (например, таблица)
let tableViewData: [String] = ["Ячейка 1", "Ячейка 2", "Ячейка 3"]
func dataForRow(at index: Int) -> String { // Быстрый доступ O(1)
    return tableViewData[index]
}

// Сценарий 3: Очередь задач (FIFO)
var taskQueue: [() -> Void] = []
func addTask(_ task: @escaping () -> Void) {
    taskQueue.append(task) // Добавление в конец — эффективно.
}
func processNextTask() {
    if !taskQueue.isEmpty {
        let nextTask = taskQueue.removeFirst() // Удаление из начала — O(n).
        nextTask()
    }
}
// Примечание: Для частых операций removeFirst лучше использовать специальную очередь.

// Сравнение с Set (который НЕ подходит для этих задач):
var set: Set<String> = ["A", "B", "C"]
// Порядок итерации не гарантирован:
for item in set { print(item) } // Может напечатать "C", "A", "B"
// Нет доступа по индексу:
// let firstElement = set[0] // Ошибка компиляции