Conjuntos (Set) em Swift 5.9: um guia detalhado
Множества (Set) в Swift
Что такое множество?
Представь, что у тебя есть коробка, в которой могут лежать только уникальные предметы. Если ты попробуешь положить туда два одинаковых яблока, второе просто не поместится — оно уже есть! В программировании такая коробка называется множеством (Set).
Множество — это коллекция, которая хранит только уникальные значения и не запоминает порядок элементов. Это очень удобно, когда нужно проверить, есть ли что-то в списке, или найти общие элементы между двумя списками.
Зачем нужно множество?
- Убирать дубликаты — если у тебя есть список покупок, где "молоко" повторяется три раза, множество оставит только одно "молоко".
- Быстрая проверка — найти, есть ли товар на складе, можно мгновенно, даже если товаров миллион.
- Сравнение списков — легко найти общие ингредиенты в двух пиццах или продукты, которые есть в одном списке, но нет в другом.
Создание множества
Чтобы создать множество, используй ключевое слово Set и квадратные скобки []:
// Пустое множество строк
var пустойНабор = Set<String>()
// Множество с числами
let числа: Set<Int> = [1, 2, 3, 4, 5]
// Множество с дубликатами (Swift сам уберет повторы)
let фрукты: Set<String> = ["яблоко", "банан", "яблоко", "апельсин"]
print(фрукты) // Выведет: ["банан", "апельсин", "яблоко"] (порядок может быть любым)
Основные операции с множествами
Добавление и удаление элементов
var корзина: Set<String> = ["молоко", "хлеб"]
корзина.insert("яйца") // Добавляем элемент
корзина.remove("хлеб") // Удаляем элемент
print(корзина) // Выведет: ["молоко", "яйца"]
Проверка наличия элемента
let контакты: Set<String> = ["Анна", "Борис", "Виктор"]
if контакты.contains("Анна") {
print("Анна есть в контактах!") // Это выполнится
}
Количество элементов
let товары: Set<String> = ["мыло", "шампунь", "зубная паста"]
print("В корзине \(товары.count) товара") // Выведет: 3
Операции между множествами
Самое интересное — это сравнение двух множеств. Представь, что у тебя есть список продуктов для пиццы от двух поваров:
let повар1: Set<String> = ["сыр", "помидор", "грибы"]
let повар2: Set<String> = ["помидор", "колбаса", "оливки"]
Объединение (union)
Все продукты, которые есть хотя бы у одного повара:
let всеПродукты = повар1.union(повар2)
print(всеПродукты) // ["сыр", "помидор", "грибы", "колбаса", "оливки"]
Пересечение (intersection)
Только те продукты, которые есть у обоих поваров:
let общиеПродукты = повар1.intersection(повар2)
print(общиеПродукты) // ["помидор"]
Разность (subtracting)
Продукты, которые есть у первого повара, но нет у второго:
let только1повар = повар1.subtracting(повар2)
print(только1повар) // ["сыр", "грибы"]
Симметричная разность (symmetricDifference)
Продукты, которые есть только у одного из поваров (не общие):
let уникальныеПродукты = повар1.symmetricDifference(повар2)
print(уникальныеПродукты) // ["сыр", "грибы", "колбаса", "оливки"]
Как решать задачи из нашего раздела?
Давай разберем типичную задачу: "Ингредиенты пиццы". Пользователь вводит строку с ингредиентами через запятую. Нужно получить уникальные ингредиенты.
Алгоритм решения:
- Получить строку от пользователя
- Разделить строку на части по запятой
- Убрать лишние пробелы у каждого ингредиента
- Поместить ингредиенты в множество (останутся только уникальные)
- Вывести результат
print("Введите ингредиенты через запятую:")
let ввод = readLine() ?? ""
// Разделяем строку на массив строк
let массивИнгредиентов = ввод.split(separator: ",")
// Создаем множество и убираем пробелы
var уникальныеИнгредиенты = Set<String>()
for ингредиент in массивИнгредиентов {
// Убираем лишние пробелы в начале и конце
let чистыйИнгредиент = ингредиент.trimmingCharacters(in: .whitespaces)
уникальныеИнгредиенты.insert(чистыйИнгредиент)
}
print("Уникальные ингредиенты:")
for ингредиент in уникальныеИнгредиенты {
print(ингредиент)
}
Частые ошибки новичков
- Забывают указать тип Set — если написать просто
let a = ["a", "b"], Swift создаст массив, а не множество. Нужно явно писатьlet a: Set<String> = ["a", "b"]. - Пытаются обратиться по индексу — у множества нет порядка, поэтому нельзя написать
множество[0]. Используй циклforили методcontains(). - Путают remove и removeAll —
remove("элемент")удаляет один элемент, аremoveAll()очищает всё множество. - Забывают про пробелы — при вводе строки пользователь может написать "сыр, помидор" (с пробелом). Всегда используй
trimmingCharacters.
Итоговый пример: "Записная книжка контактов"
Создадим программу, которая хранит уникальные имена контактов. Если пользователь пытается добавить контакт, который уже есть, программа сообщит об этом.
var контакты: Set<String> = []
print("Добро пожаловать в записную книжку!")
print("Введите имя контакта (или 'стоп' для выхода):")
while true {
let ввод = readLine() ?? ""
if ввод.lowercased() == "стоп" {
break
}
if контакты.contains(ввод) {
print("Контакт '\(ввод)' уже существует!")
} else {
контакты.insert(ввод)
print("Контакт '\(ввод)' добавлен!")
}
print("Всего контактов: \(контакты.count)")
print("Ваши контакты: \(контакты.sorted())") // sorted() нужен для красивого вывода по алфавиту
print()
}
print("До свидания!")
Почему стоит использовать множества?
Множества — это не просто удобно, но и очень быстро. Если у тебя 10 000 контактов, проверка contains() займет меньше секунды. Для массивов это было бы в 100 раз медленнее. Поэтому, когда тебе нужно работать с уникальными данными и быстро их искать — смело используй Set!
Теперь ты готов решать задачи из этого раздела. Помни: если нужно убрать дубликаты — используй множество. Если нужно найти общие элементы между двумя списками — используй intersection. Удачи!