- Создавать массив, обращаться к элементам по индексу, добавлять и удалять их
- Работать со словарями и множествами и выбирать подходящую коллекцию
- Преобразовывать коллекции с помощью
map,filterиreduce
В музыкальном приложении плейлист хранит песни в определённом порядке, телефонная книга находит номер по имени, а в списке «понравилось» одна и та же фотография не может оказаться дважды. Для этих трёх ситуаций в Swift есть три коллекции: массив (Array), словарь (Dictionary) и множество (Set).
Массивы
Массив — упорядоченный список значений одного типа, записанный в квадратных скобках. У каждого элемента есть индекс, и счёт начинается с 0: первый элемент — fruits[0]. Тип массива записывается как [String], [Int]. Массив, объявленный через var, можно менять, а массив let — нет.
var fruits = ["apple", "banana", "cherry"]
print(fruits)
print(fruits[0])
print(fruits.count)
fruits.append("pear")
fruits.insert("kiwi", at: 1)
print(fruits)
fruits.remove(at: 2)
print(fruits)
print(fruits.contains("pear"))
print(fruits.first ?? "empty")["apple", "banana", "cherry"] apple 3 ["apple", "kiwi", "banana", "cherry", "pear"] ["apple", "kiwi", "cherry", "pear"] true apple
first и last возвращают опционалы, потому что массив может быть пустым. Для перебора массива используют for-in, а если нужны и индекс, и значение — enumerated(). sorted() возвращает новый отсортированный массив, а max() и min() — наибольший и наименьший элемент (в виде опционала).
let scores = [85, 92, 78]
for (index, score) in scores.enumerated() {
print("\(index + 1). \(score)")
}
print(scores.sorted())
print(scores.max() ?? 0)
let empty: [Int] = []
print(empty.isEmpty)1. 85 2. 92 3. 78 [78, 85, 92] 92 true
Словари
Словарь хранит пары ключ: значение и находит значение не по индексу, а по ключу. Его тип записывается как [String: String]. Значение, прочитанное по ключу, всегда опционально, потому что такого ключа может не быть, — здесь очень пригодится ??. Если присвоить ключу nil, пара удаляется.
var capitals = ["Azerbaijan": "Baku", "Georgia": "Tbilisi"]
capitals["Japan"] = "Tokyo"
print(capitals["Azerbaijan"] ?? "unknown")
print(capitals["France"] ?? "unknown")
print(capitals["Japan"])
capitals["Georgia"] = nil
print(capitals.count)
for country in capitals.keys.sorted() {
print("\(country) -> \(capitals[country] ?? "")")
}Baku
unknown
Optional("Tokyo")
2
Azerbaijan -> Baku
Japan -> TokyoОдно из самых полезных применений словаря — подсчёт. Класс голосовал за любимое животное — сколько голосов получило каждое?
let votes = ["cat", "dog", "cat", "fish", "cat", "dog"]
var counts: [String: Int] = [:]
for vote in votes {
counts[vote, default: 0] += 1
}
for animal in counts.keys.sorted() {
print(animal, counts[animal, default: 0])
}cat 3 dog 2 fish 1
Множества
Множество (Set) — набор неповторяющихся значений без порядка. Если добавить одно и то же значение дважды, оно сохранится один раз. Множества очень быстро проверяют, есть ли в них элемент, и поддерживают пересечение (intersection) и объединение (union), как в математике.
var visited: Set = ["Baku", "Ganja", "Baku", "Shaki"]
print(visited.count)
visited.insert("Lankaran")
print(visited.contains("Ganja"))
let friendVisited: Set = ["Baku", "Quba"]
print(visited.intersection(friendVisited).sorted())
print(visited.union(friendVisited).sorted())3 true ["Baku"] ["Baku", "Ganja", "Lankaran", "Quba", "Shaki"]
| Коллекция | Порядок | Повторы | Когда выбирать |
|---|---|---|---|
Массив [T] | есть | можно | когда важен порядок: плейлист, очередь |
Словарь [K: V] | нет | ключи не повторяются | поиск по ключу: контакты, цены |
Множество Set<T> | нет | нельзя | уникальность и быстрая проверка: теги, посещённые города |
`map`, `filter` и `reduce`
Для обработки коллекций без циклов есть три мощных метода. map преобразует каждый элемент и создаёт новый массив, filter оставляет только элементы, подходящие под условие, а reduce сворачивает все элементы в одно значение. Код в фигурных скобках — это замыкание (closure), а $0 — текущий элемент; замыкания подробно разберём в следующем уроке.
let prices = [4, 12, 7, 20]
let doubled = prices.map { $0 * 2 }
let cheap = prices.filter { $0 < 10 }
let total = prices.reduce(0, +)
print(doubled)
print(cheap)
print(total)
print(prices.filter { $0 >= 10 }.reduce(0, +))
let names = ["aysel", "murad"]
print(names.map { $0.uppercased() })[8, 24, 14, 40] [4, 7] 43 32 ["AYSEL", "MURAD"]
Главное
- Массив упорядочен, индексы начинаются с 0; выход за границы роняет программу.
- Словарь находит значение по ключу и возвращает опционал; присваивание
nilудаляет пару. - У словарей и множеств нет порядка — для стабильного результата используй
sorted(). - Множество хранит неповторяющиеся значения и умеет
intersectionиunion. mapпреобразует,filterотбирает,reduceсворачивает.
Проверь себя
Вопросов: 10. Каждый правильный ответ приносит XP.
let a = [10, 20, 30], чему равно a[1]?