Set — это неупорядоченная коллекция уникальных элементов, реализованная как хеш-таблица. Главное отличие от Array — отсутствие дублирующих значений и отсутствие порядка. Основные интерфейсы: методы вставки (insert), удаления (remove), проверки наличия (contains).
Время выполнения:
insert, remove и contains работают в среднем за O(1).Пример использования:
var numbers: Set<Int> = [1, 2, 3] numbers.insert(4) // Set: 1, 2, 3, 4 numbers.insert(2) // Set не изменится, 2 уже присутствует numbers.remove(1) // Set: 2, 3, 4 print(numbers.contains(3)) // true
Используйте Set, когда важна уникальность, но не важен порядок. Сравните с Array:
Array выполняется за O(n).Array разрешены одинаковые значения.Сет поддерживает: ∪, ∩, −, ⊆, ⊇ и прочие теоретико-множественные операции.
Вопрос:
Будет ли следующий код компилироваться и почему?
let set: Set = [[1, 2], [3, 4]]
Ответ:
Нет, не будет. Set требует, чтобы тип элементов соответствовал протоколу Hashable. Массив (Array) не реализует Hashable, поэтому нельзя создать множества массивов напрямую. Например, Set<Int> корректен, а Set<[Int]> — нет.
История
В одном сервисе разработчики хранили уникальные идентификаторы объектов как [Int], а не Set<Int>. Это вызывало проблемы: проверки наличия и удаления работали медленно (время — O(n)), появлялись дубликаты, нарушалась бизнес-логика.
История
Попытка поместить в Set нестандартные типы (например, создавался Set<MyModel>), но тип не реализовывал Hashable. Код компилировался только после добавления соответствующих протоколов, но при реализации ошибок в hash(into:) возникали коллизии и непредсказуемое поведение во время работы.
История
Разработчик ожидал, что порядок перебора элементов в Set будет совпадать с порядком вставки, и выстраивал UI в том же порядке. В результате при каждом запуске порядок был разным, что приводило к неконсистентному отображению данных у конечного пользователя.