Массив позволяет организовать множество элементов в единое значение, в котором элементы упорядочены и могут быть получены напрямую с помощью индексов.
Массив в Swift реализует структуру данных "Массив".
При работе с массивами используются следующие типы данных:
ArrayContiguousArrayArraySliceNSArray
Основной тип данных, представляющий массив в Swift. Под капотом использует ContiguousArray или NSArray в зависимости от того, какие элементы будут храниться в массиве. В случае ссылочных (классы) и экзистенциальных типов (AnyObject, AnyClass) для хранения использует NSArray. В остальных случаях испольузется ContiguousArray.
Обеспечивает хранение элементов в непрерывной области памяти, то есть все элементы следуют в оперативной области следуют друг за другом.
Тип ArraySlice позволяете создать так называемый срез массива, указывающий на непрерывную последовательность элементов внутри Array или ContiguousArray. Особенность данного типа в том, что значения исходного массива не копируются, а ArraySlice содержит указатели на его элементы.
Для создания значения ArraySlice используется специальная семантика среза, например a[1...3] вернет значение типа ArraySlice, содержащее указатели на элементы с индексами с 1 по 3 массив a.
Сложность получения среза равно O(1) всегда, когда массив не хранит значения типа NSArray.
пишу, пишу
Изначально массив запрашивает в оперативной памяти определенный объем пространства для хранения собственных элементов. Максимально доступное количество элементов хранится в свойстве capacity. Как только значение свойства count (текущее количество элементов) превысит capacity - происходит реаллокация, то есть массив перемещается в новую область памяти. При этом значение capacity растет экспоненциально, всегда увеличиваясь в 2 раза: 0 -> 1 -> 2 -> 4 -> 8 ...
Если вы изначально знаете примерное количество элементов массива, то можете использовать метод reserveCapacity(_:) до добавления элементов, чтобы сразу выделить пространство под требуемое количество элементов и избежать затрат на реаллокацию.
Но все это работает эффективно только в случаеи использования ContiguousArray, так как NSArray не дает никакой гарантии того, как именно будут распологаться элементы в памяти.
Многие из описываемых далее операции будем производить со следующими массивами:
// плоский массив
var sourceArray = [1, 2, 3, 4, 5]
// многомерный массив
var matrixArray = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ]
// массив с опционалами
var optionalArray: Array<Int?> = [ nil, 2, nil, 4, nil, 6]
// структура для хранения в массиве
struct Man {
var name: String
var age: Int
}
// массив для хранения структуры
var structArray = [
Man(name: "Bazil", age: 30),
Man(name: "Alex", age: 42),
Man(name: "Helga", age: 21)]Обычно для создания массива используют тип Array, но если вы уверены, что элементы массива не будут ссылочными или экзистенциальными типами, то для оптимизации можно использовать ContiguousArray. В ином случае Array сам примет решение о том, значение какого типа ему создать (NSArray или ContiguousArray).
Существует несколько способов создания массивов: с помощью полного или облегченного синтаксиса, а также используя различные инициализаторы.
// 1
// Массив может быть создан с помощью облегченного синтаксиса
var numberArray = [1, 2, 3]
// в этом случае тип массива определяется автоматически
// на основании типа переданных элементов
// в массиве будут содержаться три значения типа Int
// для созданяи пустого массива можно использовать
var emptyArray = [Double]()
// в данный массив могут быть добавлены только элементы типа Double
// 2
// Массив может быть создан с помощью ключевого слова Array
// массив с 2 элементами типа Character
var alphArray = Array(arrayLiteral: Character("a"), "b")
// массив с одинаковыми элементами
var repeatingArray = Array(repeating: 0, count: 3) // [0, 0, 0]
// массив на основе диапазона
var arrayFromRange = Array(1...4) // [1, 2, 3, 4]
// массив на основе последовательности
var set = Set(arrayLiteral: 1,3,2)
var arrayFromSet = Array(set)
// в данном случае итоговый порядок элементов в массиве
// будет изменяться при каждом исполнении кода
// он зависит от хэшей элементов (протокол Hashable)
// 3
// Массив может быть создан с помощью указания полного типа данных
// массив с 3 элементами типа Float
var floatArray: Array<Float> = [1, 2, 3]
// массив c 2 элнементами типа Character
var stringArray = Array<Character>(arrayLiteral: "a", "b")--
Описание: Возвращает элемент по указанному индексу.
Сложность: О(1)
var flatArray = [1, 2, 3, 4, 5]
flatArray[2] // 3--
Описание: Возвращает количество элементов в массиве.
Сложность: О(1)
var flatArray = [1, 2, 3, 4, 5]
flatArray.count // 5--
Описание: Возвращает первый элемент (в виде опционала) в массиве или nil, если массив пустой.
var flatArray = [1, 2, 3, 4, 5]
flatArray.first // Optional(1)
var emptyArray = [Int]()
emptyArray.first // nil--
Описание: Возвращает первый элемент (в виде опционала) массива, соответствующий переданному условию или nil, если массив пустой.
var flatArray = [1, 2, 3, 4, 5]
sourceArray.first(where: { $0 > 3 }) // Optional(4)
sourceArray.first(where: { $0 > 10 }) // nil--
Описание: Возвращает последний элемент (в виде опционала) в массиве или nil, если массив пустой.
var flatArray = [1, 2, 3, 4, 5]
flatArray.last // Optional(5)
var emptyArray = [Int]()
emptyArray.last// nil--
Описание: Возвращает последний элемент (в виде опционала) массива, соответствующий переданному условию или nil, если массив пустой.
var flatArray = [1, 2, 3, 4, 5]
sourceArray.last(where: { $0 < 3 }) // Optional(2)
sourceArray.last(where: { $0 > 10 }) // nil--
Описание: Возвращает элемент массива (в виде опционала), имеющий максимальное значение.
var flatArray = [1, 2, 3, 4, 5]
flatArray.max() // Optional(5)--
Описание: Возвращает элемент массива (в виде опционала), имеющий максимальное значение, предварительно сортируя массив в соответствии с переданным замыканием.
var men = [
Man(name: "Bazil", age: 30),
Man(name: "Alex", age: 42),
Man(name: "Helga", age: 21)]
let man = men.max(by: { $0.age < $1.age })
man.name // Alex--
Описание: Возвращает элемент массива (в виде опционала), имеющий минимальное значение.
var flatArray = [1, 2, 3, 4, 5]
flatArray.min() // Optional(1)--
Описание: Возвращает элемент массива (в виде опционала), имеющий максимальное значение, предварительно сортируя массив в соответствии с переданным замыканием.
var men = [
Man(name: "Bazil", age: 30),
Man(name: "Alex", age: 42),
Man(name: "Helga", age: 21)]
let man = men.min(by: { $0.age < $1.age })
man.name // Helga| Метод/свойство | Описание | Сложность | Пример |
|---|---|---|---|
firstIndex(of:) |
Возвращает индекс первого элемента, подходящего под условие | O(n) | sourceArray.firstIndex(of: 2) |
lastIndex(of:) |
Возвращает индекс последнего элемента, подходящего под условие | O(n) | sourceArray. lastIndex(of: 2) |
| Метод/свойство | Описание | Сложность | Пример |
|---|---|---|---|
append(_:) |
Вставка элемента в конец массива | O(1) | sourceArray.append(8) |
insert(_:at:) |
Вставка элемента на указанную позицию | O(n) | optionalArray.insert(99, at: 3) |
remove(at:) |
Удаляет элемент на указанной позиции и возвращает его | O(n) | sourceArray.remove(at: 0) |
removeAll() |
Удаляет все элементы массива | O(n) | sourceArray.removeAll() |
ToDo: Удаление всех элементов, подходящих по условие
ToDo: Переделать раздел
Метод map позволяет применить переданный обработчик к каждому элементу массива. Может возвращать опциональные значения.
let editArray = sourceArray.map { $0 + 1 }
editArray // [2, 3, 4, 5, 6]
let anotherEditArray = optionalArray.map { $0 }
anotherEditArray // [nil, 2, nil, 4, nil, 6]Метод compactMap очень похож на map за тем исключением, что он возвращает только неопциональные значения.
let editArray = optionalArray.compactMap { $0 }
editArray // [2, 4, 6]Метод sort сортирует элементы исходного массива в соответствии с переданным условием.
// сортировка по возрастанию
structArray.sort { $0.age < $1.age }
structArray // [{name "Helga", age 21}, {name "Bazil", age 30}, {name "Alex", age 42}]Метод sorted возвращает новый массив, в котором элементы отсортированы в соответствии с переданным условием.
let newArray = sourceArray.sorted(by: {
$0 > $1
})
newArray // [5, 4, 3, 2, 1]Метод filter возвращает новывй массив, состоящий из тех элементов, для которых переданное замыкание возвращает true.
let men = structArray.filter { $0.age > 29 }
// содержатся все элементы с age > 29
men // [{name "Bazil", age 30}, {name "Alex", age 42}]