Swift предоставляет три основных типа коллекций , известных как массивы, наборы и словари, для хранения коллекций значений. Массивы - это упорядоченные коллекции значений. Наборы являются неупорядоченными коллекциями уникальных значений. Словари - это неупорядоченные коллекции ассоциаций ключ-значение.
Массивы, наборы и словари в Swift всегда четко определяют типы значений и ключей, которые они могут хранить. Это означает, что вы не можете вставить значение неправильного типа в коллекцию по ошибке. Это также означает, что вы можете быть уверены в типе значений, которые вы получите из коллекции.
ЗАМЕТКА
Типы массива, набора и словаря Swift реализованы в виде общих коллекций . Для получения дополнительной информации о родовых типах и коллекциях см. Обобщения .
Изменчивость коллекций
Если вы создаете массив, набор или словарь и присваиваете его переменной, созданная коллекция будет изменчивой . Это означает , что вы можете изменить (или мутируют ) коллекцию после того, как она создается путем добавления, удаления или изменения элементов в коллекции. Если вы назначаете константу массив, набор или словарь, эта коллекция является неизменной , и ее размер и содержимое не могут быть изменены.
ЗАМЕТКА
Хорошей практикой является создание неизменных коллекций во всех случаях, когда коллекция не нуждается в изменении. Это облегчит вам анализ вашего кода и позволит компилятору Swift оптимизировать производительность создаваемых вами коллекций.
Массивы
Массив хранит значения одного и того же типа в упорядоченном списке. Одно и то же значение может появляться в массиве несколько раз в разных позициях.
ЗАМЕТКА
Array
Тип Swift соединен сNSArray
классом Foundation .
Для получения дополнительной информации об использовании Array
с Фондом и Какао посмотрите Соединение между Массивом и NSArray .
Сокращенный синтаксис типа массива
Тип массива Swift записывается полностью как Array
, где Element
- тип значений, которые массиву разрешено хранить. Вы также можете записать тип массива в сокращенной форме как [Element]
. Хотя эти две формы функционально идентичны, сокращенная форма является предпочтительной и используется в этом руководстве при обращении к типу массива.
Создание пустого массива
Вы можете создать пустой массив определенного типа, используя синтаксис инициализатора:
var someInts = [Int]()
print("someInts is of type [Int] with \(someInts.count) items.")
// Prints "someInts is of type [Int] with 0 items."
Обратите внимание, что тип someInts
переменной выводится [Int]
из типа инициализатора.
В качестве альтернативы, если контекст уже предоставляет информацию о типе, такую как аргумент функции или уже типизированная переменная или константа, вы можете создать пустой массив с литералом пустого массива, который записывается как []
(пустая пара квадратных скобок):
someInts.append(3)
// someInts now contains 1 value of type Int
someInts = []
// someInts is now an empty array, but is still of type [Int]
Создание массива со значением по умолчанию
Array
Тип Swift также предоставляет инициализатор для создания массива определенного размера со всеми его значениями, установленными на одно и то же значение по умолчанию. Вы передаете этому инициализатору значение по умолчанию соответствующего типа (вызываемый repeating
): и сколько раз это значение повторяется в новом массиве (вызываемый count
):
var threeDoubles = Array(repeating: 0.0, count: 3)
// threeDoubles is of type [Double], and equals [0.0, 0.0, 0.0]
Создание массива путем добавления двух массивов вместе
Вы можете создать новый массив, сложив вместе два существующих массива с совместимыми типами с помощью оператора сложения ( +
). Тип нового массива определяется по типу двух массивов, которые вы добавляете вместе:
var anotherThreeDoubles = Array(repeating: 2.5, count: 3)
// anotherThreeDoubles is of type [Double], and equals [2.5, 2.5, 2.5]
var sixDoubles = threeDoubles + anotherThreeDoubles
// sixDoubles is inferred as [Double], and equals [0.0, 0.0, 0.0, 2.5, 2.5, 2.5]
Создание массива с литералом массива
Вы также можете инициализировать массив литералом массива , что является кратким способом записи одного или нескольких значений в виде коллекции массивов. Литерал массива записывается в виде списка значений, разделенных запятыми, которые заключены в пару квадратных скобок:
[value 1, value 2, value 3]
В приведенном ниже примере создается массив, вызываемый shoppingList
для хранения String
значений:
var shoppingList: [String] = ["Eggs", "Milk"]
// shoppingList has been initialized with two initial items
shoppingList
Переменная объявлена как «массив строковых значений», написанный в [String]
. Поскольку в этом конкретном массиве указан тип значения String
, разрешено хранить String
только значения. Здесь shoppingList
массив инициализируется двумя String
значениями ( "Eggs"
и "Milk"
), записанными в литерале массива.
ЗАМЕТКА
shoppingList
Массив объявляются как переменная (сvar
интродьюсерами) и не является постоянным (с ,let
потому что больше деталей добавляются в список покупок в приведенных ниже примерах интродьюсера).
В этом случае литерал массива содержит два String
значения и ничего больше. Это соответствует типу shoppingList
объявления переменной (массив, который может содержать только String
значения), и поэтому присваивание литерала массива разрешено как способ инициализации shoppingList
с двумя начальными элементами.
Благодаря выводу типа Swift вам не нужно писать тип массива, если вы инициализируете его литералом массива, содержащим значения того же типа. Инициализация shoppingList
могла бы быть написана в более короткой форме:
var shoppingList = ["Eggs", "Milk"]
Поскольку все значения в литерале массива имеют один и тот же тип, Swift может сделать вывод, что [String]
это правильный тип для использования с shoppingList
переменной.
Доступ и изменение массива
Вы получаете доступ к массиву и изменяете его через методы и свойства или с помощью синтаксиса нижнего индекса.
Чтобы узнать количество элементов в массиве, проверьте его count
свойство только для чтения :
print("The shopping list contains \(shoppingList.count) items.")
// Prints "The shopping list contains 2 items."
Используйте логическое isEmpty
свойство в качестве ярлыка для проверки, count
равно ли свойство 0
:
if shoppingList.isEmpty {
print("The shopping list is empty.")
} else {
print("The shopping list is not empty.")
}
// Prints "The shopping list is not empty."
Вы можете добавить новый элемент в конец массива, вызвав метод массива append(_:)
:
shoppingList.append("Flour")
// shoppingList now contains 3 items, and someone is making pancakes
В качестве альтернативы добавьте массив из одного или нескольких совместимых элементов с помощью оператора присваивания сложения ( +=
):
shoppingList += ["Baking Powder"]
// shoppingList now contains 4 items
shoppingList += ["Chocolate Spread", "Cheese", "Butter"]
// shoppingList now contains 7 items
Извлеките значение из массива, используя синтаксис индекса , передавая индекс значения, которое вы хотите получить, в квадратных скобках сразу после имени массива:
var firstItem = shoppingList[0]
// firstItem is equal to "Eggs"
ЗАМЕТКА
Первый элемент в массиве имеет индекс
0
, а не1
. Массивы в Swift всегда индексируются нулями.
Вы можете использовать синтаксис нижнего индекса, чтобы изменить существующее значение по заданному индексу:
shoppingList[0] = "Six eggs"
// the first item in the list is now equal to "Six eggs" rather than "Eggs"
Когда вы используете синтаксис нижнего индекса, указанный вами индекс должен быть действительным. Например, запись для добавления элемента в конец массива приводит к ошибке во время выполнения.shoppingList[shoppingList.count] = "Salt"
Вы также можете использовать синтаксис нижнего индекса для одновременного изменения диапазона значений, даже если замещающий набор значений имеет длину, отличную от заменяемого диапазона. Следующий пример заменяет , и с и :"Chocolate Spread""Cheese""Butter""Bananas""Apples"
shoppingList[4...6] = ["Bananas", "Apples"]
// shoppingList now contains 6 items
Чтобы вставить элемент в массив по указанному индексу, вызовите метод массива insert(_:at:)
:
shoppingList.insert("Maple Syrup", at: 0)
// shoppingList now contains 7 items
// "Maple Syrup" is now the first item in the list
Этот вызов insert(_:at:)
метода вставляет новый элемент со значением в самом начале списка покупок, обозначенным индексом ."Maple Syrup"0
Точно так же вы удаляете элемент из массива remove(at:)
методом. Этот метод удаляет элемент по указанному индексу и возвращает удаленный элемент (хотя вы можете игнорировать возвращенное значение, если оно вам не нужно):
let mapleSyrup = shoppingList.remove(at: 0)
// the item that was at index 0 has just been removed
// shoppingList now contains 6 items, and no Maple Syrup
// the mapleSyrup constant is now equal to the removed "Maple Syrup" string
ЗАМЕТКА
Если вы попытаетесь получить доступ или изменить значение для индекса, который находится за пределами существующих границ массива, вы вызовете ошибку времени выполнения. Вы можете проверить правильность индекса перед его использованием, сравнив его со
count
свойством массива . Наибольший допустимый индекс в массиве связан с тем, что массивы индексируются с нуля, однако, когда значение равно (это означает, что массив пуст), допустимых индексов нет.count - 1count0
Любые пробелы в массиве закрываются при удалении элемента, и поэтому значение индекса 0
снова равно :"Six eggs"
firstItem = shoppingList[0]
// firstItem is now equal to "Six eggs"
Если вы хотите удалить последний элемент из массива, используйте removeLast()
метод, а не remove(at:)
метод, чтобы избежать необходимости запрашивать count
свойство массива . Как и remove(at:)
метод, removeLast()
возвращает удаленный элемент:
let apples = shoppingList.removeLast()
// the last item in the array has just been removed
// shoppingList now contains 5 items, and no apples
// the apples constant is now equal to the removed "Apples" string
Итерация по массиву
Вы можете перебирать весь набор значений в массиве с помощью цикла for
- in
:
for item in shoppingList {
print(item)
}
// Six eggs
// Milk
// Flour
// Baking Powder
// Bananas
Если вам нужен целочисленный индекс каждого элемента, а также его значение, используйте enumerated()
метод для перебора массива. Для каждого элемента в массиве enumerated()
метод возвращает кортеж, состоящий из целого числа и элемента. Целые числа начинаются с нуля и считаются на единицу для каждого элемента; если вы перечислите по всему массиву, эти целые числа соответствуют индексам элементов. Вы можете разложить кортеж на временные константы или переменные как часть итерации:
for (index, value) in shoppingList.enumerated() {
print("Item \(index + 1): \(value)")
}
// Item 1: Six eggs
// Item 2: Milk
// Item 3: Flour
// Item 4: Baking Powder
// Item 5: Bananas
Более о for
- in
петлях, см For-петли .
наборы
А набор хранит различные значения одного и того же типа в сборе с не определяется упорядочением. Вы можете использовать набор вместо массива, когда порядок элементов не важен или когда вам нужно убедиться, что элемент появляется только один раз.
ЗАМЕТКА
Set
Тип Swift соединен сNSSet
классом Foundation .
Для получения дополнительной информации об использовании Set
с Основой и Какао, посмотрите Соединение между Набором и NSSet .
Хеш-значения для типов набора
Тип должен быть хешируемым , чтобы быть сохраненным в наборе, то есть тип должен обеспечивать способ вычисления значения хеша для себя. Хеш-значение - это Int
значение, которое является одинаковым для всех объектов, которые сравниваются одинаково, так что если , это следует за этим .a == ba.hashValue == b.hashValue
Все основных типов Свифта (например String
, Int
, Double
, и Bool
) являются hashable по умолчанию, и может быть использована в качестве типов заданного значения или словаря ключевых типов. Значения регистра в перечислении без связанных значений (как описано в перечислении ) также можно хэшировать по умолчанию.
ЗАМЕТКА
Вы можете использовать свои собственные пользовательские типы в качестве типов заданных значений или типов словарных ключей, приведя их в соответствие с
Hashable
протоколом из стандартной библиотеки Swift. Типы, которые соответствуютHashable
протоколу, должны предоставлятьInt
вызываемое свойство gettablehashValue
. Значение, возвращаемоеhashValue
свойством типа, не обязательно должно быть одинаковым в разных исполнениях одной и той же программы или в разных программах.
Поскольку Hashable
протокол соответствует Equatable
, соответствующие типы также должны обеспечивать реализацию оператора equals ( ==
). Equatable
Протокол требует какой - либо соответствующей реализации , ==
чтобы быть отношением эквивалентности. То есть, реализация ==
должна удовлетворять следующим трем условиям, для всех значений a
, b
и c
:
a == a
(Рефлексивность)a == b
подразумевает (симметрия)b == a
a == b && b == c
подразумевает (транзитивность)a == c
Для получения дополнительной информации о соответствии протоколам см. Протоколы .
Установить синтаксис типа
Тип набора Swift записывается как Set
, где Element
- тип, который разрешено хранить в наборе. В отличие от массивов, наборы не имеют эквивалентной сокращенной формы.
Создание и инициализация пустого набора
Вы можете создать пустой набор определенного типа, используя синтаксис инициализатора:
var letters = Set()
print("letters is of type Set with \(letters.count) items.")
// Prints "letters is of type Set with 0 items."
ЗАМЕТКА
Тип letters
переменной выводится Set
из типа инициализатора.
Альтернативно, если контекст уже предоставляет информацию о типе, такую как аргумент функции или уже типизированная переменная или константа, вы можете создать пустой набор с литералом пустого массива:
letters.insert("a")
// letters now contains 1 value of type Character
letters = []
// letters is now an empty set, but is still of type Set
Создание набора с литералом массива
Вы также можете инициализировать набор с помощью литерала массива, как краткий способ записать одно или несколько значений в виде набора множеств.
В приведенном ниже примере создается набор favoriteGenres
для хранения String
значений:
var favoriteGenres: Set = ["Rock", "Classical", "Hip hop"]
// favoriteGenres has been initialized with three initial items
favoriteGenres
Переменная объявлена как «совокупность String
значений», написанной в Set
. Поскольку этот конкретный набор указал тип значения из String
, оно только разрешено хранить String
значение. Здесь, favoriteGenres
множество инициализируется с тремя String
значениями ( "Rock"
, "Classical"
, и ), записанных в массиве буквального."Hip hop"
ЗАМЕТКА
favoriteGenres
Множество объявляются как переменная (сvar
интродьюсерами) и не является постоянным (сlet
интродьюсерами) , поскольку добавлены и удалены элементы в примерах ниже.
Тип набора не может быть выведен из одного только литерала массива, поэтому тип Set
должен быть явно объявлен. Однако из-за вывода типа Swift вам не нужно писать тип элементов набора, если вы инициализируете его литералом массива, который содержит значения только одного типа. Инициализация favoriteGenres
могла бы быть написана в более короткой форме:
var favoriteGenres: Set = ["Rock", "Classical", "Hip hop"]
Поскольку все значения в литерале массива имеют один и тот же тип, Swift может сделать вывод, что Set
это правильный тип для использования с favoriteGenres
переменной.
Доступ и изменение набора
Вы получаете доступ и изменяете набор через его методы и свойства.
Чтобы узнать количество элементов в наборе, проверьте его count
свойство только для чтения :
print("I have \(favoriteGenres.count) favorite music genres.")
// Prints "I have 3 favorite music genres."
Используйте логическое isEmpty
свойство в качестве ярлыка для проверки, count
равно ли свойство 0
:
if favoriteGenres.isEmpty {
print("As far as music goes, I'm not picky.")
} else {
print("I have particular music preferences.")
}
// Prints "I have particular music preferences."
Вы можете добавить новый элемент в набор, вызвав метод набора insert(_:)
:
favoriteGenres.insert("Jazz")
// favoriteGenres now contains 4 items
Вы можете удалить элемент из набора, вызвав метод набора remove(_:)
, который удаляет элемент, если он является членом набора, и возвращает удаленное значение или возвращает, nil
если набор не содержал его. Кроме того, все элементы в наборе могут быть удалены его removeAll()
методом.
if let removedGenre = favoriteGenres.remove("Rock") {
print("\(removedGenre)? I'm over it.")
} else {
print("I never much cared for that.")
}
// Prints "Rock? I'm over it."
Чтобы проверить, содержит ли набор определенный элемент, используйте contains(_:)
метод.
if favoriteGenres.contains("Funk") {
print("I get up on the good foot.")
} else {
print("It's too funky in here.")
}
// Prints "It's too funky in here."
Итерация по множеству
Вы можете перебирать значения в наборе с помощью цикла for
- in
.
for genre in favoriteGenres {
print("\(genre)")
}
// Classical
// Jazz
// Hip hop
Более о for
- in
петлях, см For-петли .
Set
Тип Swift не имеет определенного порядка. Чтобы перебрать значения набора в определенном порядке, используйте sorted()
метод, который возвращает элементы набора в виде массива, отсортированного с помощью <
оператора.
for genre in favoriteGenres.sorted() {
print("\(genre)")
}
// Classical
// Hip hop
// Jazz
Выполнение операций над множествами
Вы можете эффективно выполнять фундаментальные операции над множествами, например объединять два набора вместе, определять, какие значения имеют два общих набора, или определять, содержат ли два набора все, некоторые или ни одного из одинаковых значений.
Основные операции над множествами
На рисунке ниже изображены два набора - a
и b
- с результатами различных операций набора, представленных заштрихованными областями.
- Используйте
intersection(_:)
метод, чтобы создать новый набор только со значениями, общими для обоих наборов. - Используйте
symmetricDifference(_:)
метод для создания нового набора со значениями в любом наборе, но не в обоих. - Используйте
union(_:)
метод для создания нового набора со всеми значениями в обоих наборах. - Используйте
subtracting(_:)
метод для создания нового набора со значениями, не входящими в указанный набор.
let oddDigits: Set = [1, 3, 5, 7, 9]
let evenDigits: Set = [0, 2, 4, 6, 8]
let singleDigitPrimeNumbers: Set = [2, 3, 5, 7]
oddDigits.union(evenDigits).sorted()
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
oddDigits.intersection(evenDigits).sorted()
// []
oddDigits.subtracting(singleDigitPrimeNumbers).sorted()
// [1, 9]
oddDigits.symmetricDifference(singleDigitPrimeNumbers).sorted()
// [1, 2, 9]
Установить членство и равенство
Иллюстрация ниже изображает три набора a
- b
и c
- с перекрывающимися областями, представляющими элементы, общие для наборов. Набор a
- это расширенный набор b
, потому что a
содержит все элементы в b
. И наоборот, множество b
является подмножеством множества a
, поскольку все элементы в нем b
также содержатся a
. Набор b
и набор c
не пересекаются друг с другом, потому что они не имеют общих элементов.
- Используйте оператор «равно» (
==
), чтобы определить, содержат ли два набора все одинаковые значения. - Используйте
isSubset(of:)
метод, чтобы определить, содержатся ли все значения набора в указанном наборе. - Используйте
isSuperset(of:)
метод, чтобы определить, содержит ли набор все значения в указанном наборе. - Используйте методы
isStrictSubset(of:)
или,isStrictSuperset(of:)
чтобы определить, является ли набор подмножеством или надмножеством, но не равным указанному набору. - Используйте
isDisjoint(with:)
метод, чтобы определить, не имеют ли два набора общих значений.
0 комментариев