В Swift коллекции представляют собой типы, которые позволяют хранить несколько значений одного или разных типов в едином контейнере. Коллекции являются фундаментальной частью языка и широко используются во всех уровнях разработки — от простых алгоритмов до построения UI и хранения данных.
Swift предлагает три основных типа коллекций:
-
Array — упорядоченная последовательность значений
-
Set — неупорядоченное множество уникальных значений
-
Dictionary — коллекция пар "ключ-значение"
🔢 Array
Общая характеристика:
-
Упорядоченная коллекция.
-
Позволяет дублирующие элементы.
-
Доступ по индексу: O(1).
-
Элементы индексируются с нуля.
-
Тип: Array<Element> или [Element].
Объявление:
var numbers: [Int] = [1, 2, 3]
var strings = ["one", "two", "three"]
Особенности:
-
Поддерживает множество методов: append, insert, remove, sort, map, filter, reduce.
-
При добавлении за пределами текущей ёмкости создаётся новая копия (Copy-on-Write).
-
Можно инициализировать пустым: var list = String
-
Может быть многомерным: [[Int]] — двумерный массив.
Пример:
var fruits = ["Apple", "Banana"]
fruits.append("Mango")
let first = fruits[0] // "Apple"
🔘 Set
Общая характеристика:
-
Неупорядоченное множество.
-
Все элементы уникальны.
-
Доступ к элементу: O(1) в среднем.
-
Тип: Set<Element>
Объявление:
var tags: Set<String> = ["swift", "ios", "xcode"]
Особенности:
-
Использует хеш-таблицу.
-
Элемент должен быть Hashable (напр. Int, String, Enum, Struct с Hashable).
-
Методы: insert, remove, contains, union, intersection, subtracting.
Пример:
var uniqueNumbers: Set = [1, 2, 3]
uniqueNumbers.insert(2) // Не будет добавлен
uniqueNumbers.contains(3) // true
🧾 Dictionary
Общая характеристика:
-
Хранит пары "ключ — значение".
-
Ключи должны быть уникальными.
-
Использует хеширование ключей.
-
Доступ к значению по ключу: O(1) в среднем.
-
Тип: Dictionary<Key, Value> или [Key: Value]
Объявление:
var capitals: [String: String] = [
"France": "Paris",
"Japan": "Tokyo"
]
Особенности:
-
Ключи должны быть Hashable.
-
Методы: updateValue, removeValue, merge, mapValues, filter.
-
Можно итерировать по keys, values, items.
Пример:
capitals["Germany"] = "Berlin"
let city = capitals["France"] // "Paris"
📐 Расширенные коллекции и структуры
Range
-
Представляет диапазон значений.
-
Может быть закрытым (1...5) или полуоткрытым (1..<5).
-
Используется для индексации, цикла и генерации диапазонов.
for i in 1...3 {
print(i)
}
Stride
-
Позволяет шагать по числовым диапазонам с шагом.
-
stride(from:to:by:), stride(from:through:by:).
for angle in stride(from: 0, through: 360, by: 90) {
print(angle)
}
📂 Коллекции по протоколам
Swift коллекции реализуют множество протоколов, определяющих их поведение:
Sequence
-
Основной протокол последовательностей.
-
Обеспечивает итерацию через for-in.
-
Обязателен метод makeIterator().
let sequence = [1, 2, 3]
for num in sequence {
print(num)
}
Collection
-
Расширяет Sequence.
-
Определяет индексы, доступ по индексу, длину и навигацию.
-
Требует свойств: startIndex, endIndex, index(after:).
BidirectionalCollection
-
Позволяет двигаться назад: index(before:).
-
Пример: Array, String.
RandomAccessCollection
-
Поддерживает произвольный доступ к элементам: O(1).
-
Позволяет сравнивать производительность и выбирать алгоритмы в зависимости от коллекции.
MutableCollection
- Позволяет изменять элементы по индексу.
var numbers = [1, 2, 3]
numbers[0] = 10
🧠 Copy-on-Write (COW) в коллекциях
Коллекции в Swift используют механизм Copy-on-Write:
-
При копировании коллекции объект не дублируется сразу.
-
Если копия не изменяется, она разделяет память с оригиналом.
-
Если копия модифицируется, создаётся новая память.
Это позволяет эффективно использовать память и при этом сохранить семантику значений (value semantics).
🔄 Высокоуровневые методы работы с коллекциями
Swift предоставляет функциональные методы:
-
map: преобразует элементы
-
filter: фильтрует по условию
-
reduce: сворачивает в одно значение
-
sorted, reversed, prefix, suffix, drop
Пример:
let numbers = [1, 2, 3, 4]
let squares = numbers.map { $0 \* $0 } // [1, 4, 9, 16]
let even = numbers.filter { $0 % 2 == 0 } // [2, 4]
let sum = numbers.reduce(0, +) // 10
🧱 Специализированные коллекции
ArraySlice
-
Представляет часть массива без копирования данных.
-
Используется при разделении: array[1..<4]
IndexSet
- Оптимизированный способ хранения множества целых индексов.
let indexes = IndexSet([1, 2, 3])
OrderedDictionary (из Swift Collections)
-
Коллекция, которая сохраняет порядок ключей.
-
Доступна через пакет swift-collections.
🧰 Коллекции и обобщения
Swift коллекции обобщены (generic), что позволяет создавать универсальные структуры данных:
struct Stack<T> {
private var items: [T] = []
mutating func push(_ item: T) {
items.append(item)
}
mutating func pop() -> T? {
return items.popLast()
}
}
Это позволяет использовать тип Stack<Int>, Stack<String> и т. д.
🔒 Коллекции и безопасность типов
Swift строго типизирован: коллекции всегда содержат только элементы одного типа. Это позволяет избежать ошибок времени выполнения и использовать весь потенциал компилятора и автодополнения.
let names: [String] = ["Alice", "Bob"]
// names.append(42) // Ошибка компиляции
🧪 Итерирование по коллекциям
Можно использовать:
-
for-in
-
forEach
-
enumerated()
-
indices
-
zip
Пример с индексами:
for (index, value) in array.enumerated() {
print("\\(index): \\(value)")
}
Все коллекции в Swift проектируются так, чтобы быть:
-
безопасными,
-
предсказуемыми,
-
быстрыми,
-
легко читаемыми и модифицируемыми.