Skip to content

Latest commit

 

History

History
executable file
·
347 lines (233 loc) · 15.5 KB

File metadata and controls

executable file
·
347 lines (233 loc) · 15.5 KB

Массивы

Содержание

Описание

Массив позволяет организовать множество элементов в единое значение, в котором элементы упорядочены и могут быть получены напрямую с помощью индексов.

Массив в Swift реализует структуру данных "Массив".

Типы данных

При работе с массивами используются следующие типы данных:

  • Array
  • ContiguousArray
  • ArraySlice
  • NSArray

Тип Array

Основной тип данных, представляющий массив в Swift. Под капотом использует ContiguousArray или NSArray в зависимости от того, какие элементы будут храниться в массиве. В случае ссылочных (классы) и экзистенциальных типов (AnyObject, AnyClass) для хранения использует NSArray. В остальных случаях испольузется ContiguousArray.

Тип ContiguousArray

Обеспечивает хранение элементов в непрерывной области памяти, то есть все элементы следуют в оперативной области следуют друг за другом.

Тип ArraySlice

Тип ArraySlice позволяете создать так называемый срез массива, указывающий на непрерывную последовательность элементов внутри Array или ContiguousArray. Особенность данного типа в том, что значения исходного массива не копируются, а ArraySlice содержит указатели на его элементы.

Для создания значения ArraySlice используется специальная семантика среза, например a[1...3] вернет значение типа ArraySlice, содержащее указатели на элементы с индексами с 1 по 3 массив a.

Сложность получения среза равно O(1) всегда, когда массив не хранит значения типа NSArray.

Тип 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")

Доступ к элементам массива

--

subscript

Описание: Возвращает элемент по указанному индексу.

Сложность: О(1)

var flatArray = [1, 2, 3, 4, 5]
flatArray[2] // 3

--

Свойство count

Описание: Возвращает количество элементов в массиве.

Сложность: О(1)

var flatArray = [1, 2, 3, 4, 5]
flatArray.count // 5

--

Свойство first

Описание: Возвращает первый элемент (в виде опционала) в массиве или nil, если массив пустой.

var flatArray = [1, 2, 3, 4, 5]
flatArray.first // Optional(1)

var emptyArray = [Int]()
emptyArray.first // nil

--

Метод first(where:)

Описание: Возвращает первый элемент (в виде опционала) массива, соответствующий переданному условию или nil, если массив пустой.

var flatArray = [1, 2, 3, 4, 5]
sourceArray.first(where: { $0 > 3 }) // Optional(4)
sourceArray.first(where: { $0 > 10 }) // nil

--

Свойство last

Описание: Возвращает последний элемент (в виде опционала) в массиве или nil, если массив пустой.

var flatArray = [1, 2, 3, 4, 5]
flatArray.last // Optional(5)

var emptyArray = [Int]()
emptyArray.last// nil

--

Метод last(where:)

Описание: Возвращает последний элемент (в виде опционала) массива, соответствующий переданному условию или nil, если массив пустой.

var flatArray = [1, 2, 3, 4, 5]
sourceArray.last(where: { $0 < 3 }) // Optional(2)
sourceArray.last(where: { $0 > 10 }) // nil

--

Метод max()

Описание: Возвращает элемент массива (в виде опционала), имеющий максимальное значение.

var flatArray = [1, 2, 3, 4, 5]
flatArray.max() // Optional(5)

--

Метод max(by:)

Описание: Возвращает элемент массива (в виде опционала), имеющий максимальное значение, предварительно сортируя массив в соответствии с переданным замыканием.

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

--

Метод min()

Описание: Возвращает элемент массива (в виде опционала), имеющий минимальное значение.

var flatArray = [1, 2, 3, 4, 5]
flatArray.min() // Optional(1)

--

Метод min(by:)

Описание: Возвращает элемент массива (в виде опционала), имеющий максимальное значение, предварительно сортируя массив в соответствии с переданным замыканием.

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}]

Дополнительная информация