В каких случаях в Swift следует использовать тип Set?

Ответ

Тип Set в Swift — это неупорядоченная коллекция уникальных элементов. Его используют, когда важны следующие операции:

  1. Гарантия уникальности – автоматическое удаление дубликатов при вставке.
    let ids: Set = [101, 102, 101, 103] // [101, 102, 103] (порядок может быть любым)
  2. Быстрая проверка принадлежности (contains) – выполняется за O(1) в среднем, что значительно быстрее, чем O(n) у Array.
    let allowedTags: Set = ["VIP", "Premium", "New"]
    if allowedTags.contains(userTag) { // Мгновенная проверка
        grantAccess()
    }
  3. Теоретико-множественные операции – эффективное выполнение операций над коллекциями.

    let developers: Set = ["Alice", "Bob", "Charlie"]
    let designers: Set = ["Bob", "Diana"]
    
    let team = developers.union(designers) // Все: ["Alice", "Bob", "Charlie", "Diana"]
    let bothRoles = developers.intersection(designers) // Только Bob: ["Bob"]
    let onlyDevs = developers.subtracting(designers) // Devs, не являющиеся дизайнерами: ["Alice", "Charlie"]

Когда НЕ использовать Set:

  • Когда важен порядок элементов – используйте Array.
  • Когда нужны дубликаты значений – используйте Array.
  • Когда требуется частая индексация по целочисленному индексу – Array эффективнее.

Примечание: Для собственных типов в Set необходимо, чтобы тип соответствовал протоколу Hashable.

Ответ 18+ 🔞

Так, слушай, про этот ваш Set в Swift. Представь себе мешок, обычный мешок, куда ты кидаешь вещи. Но мешок этот — волшебный, ёпта. Он ненавидит одинаковые носки. Кинешь две пары одинаковых — одна тут же испаряется, в рот меня чих-пых! И порядок ему похуй, он там всё внутри как бог на душу положит, трясёт, и всё.

Вот зачем он нужен, этот чудак-мешок:

  1. Уникальность, блядь. Самый главный пункт. Ты ему: «Держи 101, 102, 101, 103». А он тебе: «Пошёл нахуй со своим вторым 101, я уже один есть!». И останется [101, 102, 103]. Порядок, конечно, может быть [103, 101, 102] — ему же похую.

    let ids: Set = [101, 102, 101, 103] // [101, 102, 103] (а порядок — как карта ляжет)
  2. Проверка «а есть ли чёрт?» — мгновенная. Это его суперсила, ёбана! У Array (массива) чтобы найти элемент, надо перебрать всё, от начала до конца, это O(n), можно заскучать. А Set — он как хитрая жопа с картотекой. Спросил его: «Э, Сет, а "VIP" у тебя есть?». Он — хвать! — и сразу: «Да, есть, на!» или «Не, не, такого не держим». За O(1), то есть практически моментально.

    let allowedTags: Set = ["VIP", "Premium", "New"]
    if allowedTags.contains(userTag) { // Щёлк — и готово, даже не вспотел
        grantAccess()
    }
  3. Операции как в школе на математике, только полезные. Объединение, пересечение, вычитание — всё это делается в пару команд, без этих твоих циклов и проверок.

    let developers: Set = ["Alice", "Bob", "Charlie"]
    let designers: Set = ["Bob", "Diana"]
    
    let team = developers.union(designers) // Все скопом: ["Alice", "Bob", "Charlie", "Diana"]
    let bothRoles = developers.intersection(designers) // Те, кто и там и там: только ["Bob"]
    let onlyDevs = developers.subtracting(designers) // Чистые разработчики, без дизайнерской пошлины: ["Alice", "Charlie"]

А когда его, блядь, использовать НЕ НАДО? Да очень просто:

  • Если тебе важен порядок — типа очередь в столовой. Бери Array. Сет всё перетасует, пидарас шерстяной.
  • Если тебе нужны дубликаты — например, учёт патронов, их же много одинаковых. Опять Array.
  • Если ты постоянно лезешь к элементам по индексу (array[5]) — Set тебе этого не позволит, у него индексы — тёмный лес. Только Array.

Важный нюанс, блядь, на посошок: Если ты захочешь пихнуть в Set свою собственную структуру или класс (типа struct Pirate), то этот твой тип должен подчиняться протоколу Hashable. А то Set не поймёт, как сравнивать и искать твоих пиратов, и будет ругаться, как сапожник.