Массивы (Array)
Массив - это еще один тип коллекций в программировании на Swift. Массив хранит различные значения одного типа в виде коллекции в упорядоченной форме. Порядок элемента задается благодаря положению в массиве через индекс. Индексы Можно использовать множества как альтернативу массиву, когда порядок элементов значения не имеет или когда необходимо быть уверенным в том, что значения внутри коллекции не повторяются.
Массив - это коллекция неуникальных упорядоченных однотипных данных.
Массив в Swift можно представить как поезд с вагонами, которые идут друг за другом с определенными порядком. Если поменять вагоны местами, то и их номера в порядке тоже поменяются. Например, поменять местами первый и последний вагон. Тогда первый вагон будет с порядковым номером последнего, а последний станет под порядковым номером 1.
Что из себя представляет массив?
В массиве можно хранить однотипные данные в определенном порядке и при этом элементы массива могут повторятся.
Пример:
let names = ["Arthur", "Ford", "Trillian", "Zaphod", "Marvin"]
print(names)
// Output
// ["Arthur", "Ford", "Trillian", "Zaphod", "Marvin"]
Нельзя изменить тип массива после того, как он был объявлен.
В квадратных скобках помещаются элементы массива. Элементы разделяются между собой запятыми. Индексы представляют собой элементы последовательности целых положительных чисел, начиная с нуля. Первый элемент массива имеет индекс “0”, второй элемент массива - индекс “1” и так далее.
Все элементы массива должны быть единого типа данных.
Если в качестве значений элементов необходимо указать данные разных типов, тогда тип данных для элементов в массиве будет по типу “Any”.
Создание массива
Если создать массив и присвоить его переменной, то созданная коллекция будет изменяемой. Это обозначает, что можно изменить коллекцию после ее создания путем добавления, удаления или изменения элементов этой коллекции. И наоборот, когда вы присвоите массив константе, то массив будет неизменяемым, а его размер и содержимое не может быть изменено.
Тип массива в Swift в полной форме пишется как Array<Element>, где Element - это тип данных элементов массива.
В сокращенной форме тип данных массива можно написать как [Element].
Хотя две формы функционально идентичны, краткая форма является предпочтительной и используется чаще.
Декларирование массива. В этом примере - элементы будут со строковым типом данных:
var array1: Array<String>
Или так:
var array2: [String]
После объявления массива для дальнейшей работы необходимо инициализировать массив:
array1 = ["Adam"]
array2 = ["Ben"]
Общая форма объявления и инициализации массива:
var array3: Array<String> = ["Adam", "Ben", "Chack"]
var array4: [String] = ["Dilan", "Ellon", "Finn"]
Еще одна форма объявления и инициализации массива (Создание массива с литералом массива):
var array5 = Array<String>(arrayLiteral: "Gin", "Henry", "Isaak")
var array6 = [String](arrayLiteral: "John", "Kim", "Lasly")
Таким способом создается новый экземпляр коллекции, который содержит элементы последовательности. В данном примере - последовательность строковых элементов.
В случае
array5
требуется добавлять элементы того типа, который указан (Array). Если вместо *Array * указать *Array*, то тип данных массива будет определен исходя из типа элементов. Если элементы будут разного типа, то тогда тип данных массива будет *Any*.
Объявление и инициализация массива без указания типа данных (Создание массива с литералом массива):
var array7 = ["Mary", "Nansy", "Olaph"]
Тип коллекции будет определен исходя из типа данных элементов, с которыми коллекция инициализируется. Такая сокращенная форма используется чаще всего.
Еще один способ инициализации массива с помощью повторяющегося значения. Указывается элемент, с которым массив инициализируется и количество раз, сколько он повторяется в массиве:
let array8 = Array(repeating: "Z", count: 5)
print(array8)
// Output
// ["Z", "Z", "Z", "Z", "Z"]
Объявление пустого словаря с помощью пустого инициализатора:
let array9 = [String]()
print(array9)
// Output
// []
let array10 = Array<String>()
print(array10)
// Output
// []
Еще один способ объявления пустого словаря с помощью присвоение значения пустого массива:
let array11: [String] = []
print(array11)
// Output
// []
Просто присвоить пустой массив без указания типа - нельзя, так как будет ошибка: нельзя определить тип данных элементов массива.
Работа с массивом
Можно получить доступ к массиву и изменять его либо через его методы и свойства, либо используя синтаксис индексов.
Работа с элементами массива: добавление, получение, изменение и удаление элементов массива
Массивы — это коллекция элементов одного типа. Каждый элемент имеет числовой индекс, начиная с 0.
Для примера работы со массивом создаем массив “names”:
var names = ["Arthur", "Ford", "Trillian", "Zaphod", "Marvin"]
print(names)
// Output
// ["Arthur", "Ford", "Trillian", "Zaphod", "Marvin"]
Если выписать индексы и значения, получим:
0: Arthur
1: Ford
2: Trillian
3: Zaphod
4: Marvin
Добавление элемента массива
Для добавления нового элемента в конец массива:
names.append("Eddie")
print(names)
// Output
// ["Arthur", "Ford", "Trillian", "Zaphod", "Marvin", "Eddie"]
Используется метод append(Element)
, чтобы добавить новый элемент в конец массива. Добавляемый элемент должен иметь тот же тип, что и другие элементы в коллекции.
Сложность
O(1) в среднем по многим вызовам
append(Element)
в одном и том же массиве.
Также можно комбинировать массивы. Для этого можно использовать операторы +
и +=
(операторы сложения и присваивания):
names += ["Heart of Gold"]
print(names)
// Output
// ["Arthur", "Ford", "Trillian", "Zaphod", "Marvin", "Eddie", "Heart of Gold"]
Вставка элементов в массив
Вставка элементов в массив аналогична удалению элементов. Для этого используется метод insert(_:, at:)
:
names.insert("Humma Kavula", at: 4)
Метод insert(Element, at: Int)
вставляет в массив элемент по указанному индексу, Этот код вставит новое имя в индекс 4. Это означает, что элемент, который был в позиции 4, теперь сместится на одну позицию вправо.
Удаление элементов массива
Удаление элемента из массива по индексу - с индексом 2:
names.remove(at: 2)
print(names)
// Output
// ["Arthur", "Ford", "Zaphod", "Marvin", "Eddie", "Heart of Gold"]
Это удалит элемент Trillian
из массива, потому что этот элемент имеет индекс 2
.
Хотя Trillian
является третьим элементом в массиве names
, тем не менее, он имеет индекс 2, потому что массивы имеют нулевую индексацию. Каждый массив начинаются с индекса 0, поэтому любой n-й элемент имеет индекс n — 1.
Метод remove(at: Int)
также возвращает удаленный элемент. То есть, можно его использовать:
var measurements: [Double] = [1.1, 1.5, 2.9, 1.2, 1.5, 1.3, 1.2]
let removed = measurements.remove(at: 2)
print(measurements)
// Output
// [1.1, 1.5, 1.2, 1.5, 1.3, 1.2]
print(removed)
// Output
// 2.9
Еще несколько полезных методов удаления элементов из массива:
- removeFirst() - удаляет первый элемент из массива и возвращает его;
- removeFirst(Int) - удаляет указанное количество элементов, начиная с начала;
- removeLast() - удаляет последний элемент из массива и возвращает его;
- removeLast(Int) - удаляет указанное количество элементов, начиная с конца;
- removeSubrange(Range
) - удаляет из массива элементы с индексами, которые соответствуют указанному диапазону; - popLast() - удаляет и возвращает последний элемент коллекции. Возвращаемое значение: последний элемент коллекции, если коллекция не пуста, в противном случае - nil.
Получение и изменение элементов массива
Можно получить значение элемента массива с помощью его индекса:
var names = ["Arthur", "Ford", "Trillian", "Zaphod", "Marvin"]
let user = names[2]
print(user)
// Output
// Trillian
Также можно использовать данный синтаксис для изменения массива:
names[2] = "Prostetnic Vogon Jeltz"
print(names)
// Output
// ["Arthur", "Ford", "Prostetnic Vogon Jeltz", "Zaphod", "Marvin"]
Можно менять часть элементов интервалами:
names[1...3] = ["Dart", "Yoda"]
print(names)
// Output
// ["Arthur", "Dart", "Yoda", "Marvin"]
этой командой мы удаляем 3 элементов (с первого по третий) и вместо них вставляем два новых, т.е. изменяться может так же и число элементов.
Работа с массивом
Можно узнать количество элементов в массиве через его read-only свойство count:
var names = ["Arthur", "Ford", "Trillian", "Zaphod", "Marvin"]
let countItem = names.count
print(countItem)
// Output
// 5
Логическое свойство isEmpty вернет true
если массив пустой и вернет false
- если массив не пустой.
Пример:
var names = ["Arthur", "Ford", "Trillian", "Zaphod", "Marvin"]
if names.isEmpty {
print("Array is empty")
} else {
print("Array is not empty")
}
// Output
// Array is not empty
Метод contains(_:)
вернет true
если в массиве есть указанный в методе элемент и вернет false
- если в массиве нет такого элемента.
Свойство first
— возвращает первый элемент массива (опциональный тип)
Свойство last
— возвращает последний элемент массива (опциональный тип)
Метод randomElement()
- возвращает случайный элемент массива (опциональный тип)
Сложность
randomElement()
O(1), если коллекция соответствует RandomAccessCollection; в противном случае O(n), где n — длина коллекции.
Пример:
var names = ["Arthur", "Ford", "Trillian", "Zaphod", "Marvin"]
if let firstName = names.first {
print(firstName)
}
// Output
// Arthur
if let lastName = names.last {
print(lastName)
}
// Output
// Marvin
Массивы можно объединять. В результате будет новый массив, в котором будут элементы первого и второго массива.
Внимание! Порядок сложения массивов важен.
Пример:
var numbers1 = [1, 2, 3]
var numbers2 = [7, 8, 9]
var numbers3 = numbers1 + numbers2
print(numbers3)
// Output
// [1, 2, 3, 7, 8, 9]
var numbers4 = numbers2 + numbers1
print(numbers4)
// Output
// [7, 8, 9, 1, 2, 3]
Если объединить массивы с разными типами данных, то результирующий массив будет с типом *Array
var numbrs5 = numbers1 + ["5"]
print(numbrs5, type(of: numbrs5))
// Output
// [1, 2, 3, "5"] Array<Any>
Итерация по массиву - Перебор значений массива с помощью цикла
Цикл for-in позволит последовательно перебрать все элементы массива:
let names = ["Arthur", "Ford", "Trillian", "Zaphod", "Marvin"]
for name in names {
print(name)
}
// Output
// Arthur
// Ford
// Trillian
// Zaphod
// Marvin
Приведенный выше код выведет каждый элемент names
. Внутри тела цикла for-in можно использовать локальную константу name
в качестве текущего элемента. Каждый раз, когда цикл запускается, элемент из коллекции names
назначается константе name
и выполняется тело цикла. Это позволит выполнить некоторый код для каждого элемента в коллекции.
Также, можно перебрать массив по индексам. В этом случае следует учитывать, что индекс первого элемента будет ноль. Тогда индекс второго - 1, а последнего - на единицу меньше от количества элементов в массиве. Таким образом диапазон перебора по индексам можно записать таким образом:
- 0…array.count - 1
Или
- 0..<array.count
Подробнее о диапазонах - смотреть в отдельной статье.
Следует учитывать, что теперь в каждой итерации локальной константе в качестве значения будет присвоено значение из этого диапазона, что соответствует индексам массива. А это обозначает, что теперь для получения элемента массива следует обращаться к массиву по индексу.
Пример:
let names = ["Arthur", "Ford", "Trillian", "Zaphod", "Marvin"]
for index in 0...names.count - 1 {
print(names[index])
}
// Output
// Arthur
// Ford
// Trillian
// Zaphod
// Marvin
Метод enumerated()
позволяет получить последовательность пар из индекса и значения элементов массива:
let names = ["Arthur", "Ford", "Trillian", "Zaphod", "Marvin"]
for (index, value) in names.enumerated() {
print("\(index) - \(value)")
if (value == "Ford") {
print(index)
}
}
// Output
// 0 - Arthur
// 1 - Ford
// 1
// 2 - Trillian
// 3 - Zaphod
// 4 - Marvin
Еще несколько полезных свойств и методов
Метод index(of:) - возвращает первый индекс, в котором указанное значение появляется в коллекции. Возвращаемое значение опционального типа, так как такого элемента может не оказаться в коллекции.
Метод min() - возвращает минимальный элемент в последовательности. Возвращаемое значение опционального типа, так как такого элемента может не оказаться в коллекции.
Метод max() - возвращает максимальный элемент в последовательности. Возвращаемое значение опционального типа, так как такого элемента может не оказаться в коллекции.
Метод dropFirst(_:Int) - возвращает подпоследовательность, содержащую все, кроме заданного количества начальных элементов. В аргументах указывается количество элементов, которые необходимо удалить с начала коллекции. Это значение должно быть больше или равно нулю. Если количество отбрасываемых элементов превышает количество элементов в коллекции, результатом является пустая подпоследовательность.
let numbers = [1, 2, 3, 4, 5]
print(numbers.dropFirst(2))
// Output
// [3, 4, 5]
print(numbers.dropFirst(10))
// Output
// []
Метод dropLast(_:Int) - возвращает подпоследовательность, содержащую все, кроме заданного количества конечных элементов. В аргументах указывается количество элементов, которые необходимо удалить с конца коллекции. Это значение должно быть больше или равно нулю. Если количество отбрасываемых элементов превышает количество элементов в коллекции, результатом является пустая подпоследовательность.
let numbers = [1, 2, 3, 4, 5]
print(numbers.dropLast(2))
// Output
// [1, 2, 3]
print(numbers.dropLast(10))
// Output
// []
Метод reverse() - меняет местами элементы в массиве в обратном порядке. В итоге исходный массив меняется.
var number = [1, 2, 3, 4]
number.reverse()
print(number)
// Output
// [4, 3, 2, 1]
Метод reversed() - возвращает массив с элементами исходной коллекции в обратном порядке. В итоге исходный массив не меняется, так как создается новая коллекция.
var number = [1, 2, 3, 4]
var numberReversed = number.reversed()
print(number)
// Output
// [1, 2, 3, 4]
print(numberReversed)
// Output
// [4, 3, 2, 1]
Метод joined(separator: String) - возвращает новую строку, объединяя элементы последовательности, добавляя заданный разделитель между каждым элементом. separator - строка для вставки между каждым из элементов в этой последовательности. Разделителем по умолчанию является пустая строка.
let cast = ["Vivien", "Marlon", "Kim", "Karl"]
let list = cast.joined(separator: ", ")
print(list)
// Output
// Vivien, Marlon, Kim, Karl
Метод swapAt(Self.Index, Self.Index) - меняет местами два элемента в массиве согласно указаных в методе индексов.
Примечание: swapAt() вызовет фатальную ошибку, если попытаться выполнить обмен за пределы длины массива.
var numbers = [1, 2, 3, 4, 5]
print(numbers)
// Output
// [1, 2, 3, 4, 5]
numbers.swapAt(0, 1)
print(numbers)
// Output
// [2, 1, 3, 4, 5]
Еще полезные ссылки
Также информацию по массивам можно получить на странице официальной документации (Узнать больше про методы и свойства массивов).
Ссылки на официальную документацию: