Типы набора
Swift обеспечивает три основных типа набора, известные как массивы, наборы и словари, для хранения наборов значений. Массивам упорядочивают наборы значений. Наборам не упорядочивают наборы отличных значений. Словарям не упорядочивают наборы ассоциаций значения ключа.
Массивы, наборы и словари в Swift всегда соглашаются с типами значений и ключей, которые они могут сохранить. Это означает, что Вы не можете вставить значение неправильного типа в набор по ошибке. Это также означает, что можно быть уверены в типах значений, которые Вы получите от набора. Использование Swift типизированных массивов, наборов и словарей гарантирует, что Ваш код всегда соглашается с типами значений, с которыми набор может работать и позволяет Вам поймать любые несоответствия типов рано в разработке Вашего кода.
Переменчивость наборов
Если Вы создадите массив, набор или словарь и присвоите его переменной, то создающийся набор будет непостоянным. Это означает, что можно измениться (или видоизмениться), набор после того, как он создается путем добавления, удаляя или изменяя элементы в наборе. С другой стороны при присвоении массива, набора или словаря к константе, тот набор является неизменным, и его размер, и содержание не может быть изменено.
Массивы
Массив хранит значения того же типа в упорядоченном списке. То же значение может появиться в массиве многократно в различных позициях.
Краткий синтаксис типа массива
Тип массива Swift записан полностью как Array<SomeType>
, где SomeType
тип значений, которые массиву позволяют сохранить. Можно также записать тип массива в краткой форме как [SomeType]
. Несмотря на то, что две формы функционально идентичны, краткая форма предпочтена и используется всюду по этому руководству при обращении к типу массива.
Создание и инициализация массива
Можно создать пустой массив определенного типа с помощью синтаксиса инициализатора:
var someInts = [Int]()
println("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]
Swift Array
тип также обеспечивает инициализатор для создания массива определенного размера со всем его набором значений к предоставленному значению по умолчанию. Вы передаете этот инициализатор число элементов, которые будут добавлены к новому массиву (вызванный count
) и значение по умолчанию надлежащего типа (вызванный repeatedValue
):
var threeDoubles = [Double](count: 3, repeatedValue: 0.0)
// threeDoubles is of type [Double], and equals [0.0, 0.0, 0.0]
Можно создать новый массив путем добавления вместе двух существующих массивов с совместимыми типами с оператором сложения (+
). Тип нового массива выведен из типа двух массивов, которые Вы добавляете вместе:
var anotherThreeDoubles = [Double](count: 3, repeatedValue: 2.5)
// anotherThreeDoubles is inferred as [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"
), записанный в литерале массивов.
В этом случае литерал массивов содержит два String
значения и ничто иное. Это соответствует тип shoppingList
объявление переменной (массив, который может только содержать String
значения), и таким образом, присвоение литерала массивов разрешено как способ инициализировать shoppingList
с двумя начальными элементами.
Благодаря выводу типа Swift Вы не должны писать тип массива при инициализации его с литералом массивов, содержащим значения того же типа. Инициализация shoppingList
возможно, был записан в более короткой форме вместо этого:
var shoppingList = ["Eggs", "Milk"]
Поскольку все значения в литерале массивов имеют тот же тип, Swift может вывести это [String]
корректный тип для использования для shoppingList
переменная.
Доступ и изменение массива
Вы получаете доступ и изменяете массив через его методы и свойства, или при помощи нижнего синтаксиса.
Для обнаружения числа элементов в массиве проверьте его только для чтения count
свойство:
println("The shopping list contains \(shoppingList.count) items.")
// prints "The shopping list contains 2 items."
Используйте булевскую переменную isEmpty
свойство как ярлык для проверки, ли count
свойство равно 0
:
if shoppingList.isEmpty {
println("The shopping list is empty.")
} else {
println("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"
Можно также использовать нижний синтаксис для изменения диапазона значений сразу, даже если заменяющий набор значений имеет различную длину, чем диапазон, который Вы заменяете. Следующие замены в качестве примера "Chocolate Spread"
, "Cheese"
, и "Butter"
с "Bananas"
и "Apples"
:
shoppingList[4...6] = ["Bananas", "Apples"]
// shoppingList now contains 6 items
Для вставки элемента в массив в указанном индексе вызовите массив insert(_:atIndex:)
метод:
shoppingList.insert("Maple Syrup", atIndex: 0)
// shoppingList now contains 7 items
// "Maple Syrup" is now the first item in the list
Этот вызов к insert(_:atIndex:)
метод вставляет новый элемент со значением "Maple Syrup"
в самом начале списка покупок, обозначенного индексом 0
.
Точно так же Вы удаляете элемент из массива с removeAtIndex(_:)
метод. Этот метод удаляет элемент в указанном индексе и возвращает удаленный элемент (несмотря на то, что можно проигнорировать возвращенное значение, если Вам не нужен он):
let mapleSyrup = shoppingList.removeAtIndex(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
Когда элемент удален, и таким образом, значение в индексе, любые разрывы в массиве преодолены 0
еще раз равно "Six eggs"
:
firstItem = shoppingList[0]
// firstItem is now equal to "Six eggs"
Если Вы хотите удалить заключительный элемент из массива, используйте removeLast()
метод, а не removeAtIndex(_:)
метод для предотвращения потребности запросить массив count
свойство. Как removeAtIndex(_:)
метод, 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 {
println(item)
}
// Six eggs
// Milk
// Flour
// Baking Powder
// Bananas
При необходимости в целочисленном индексе каждого элемента, а также его значения используйте глобальную переменную enumerate
функция для итерации по массиву вместо этого. enumerate
функционируйте возвращает кортеж для каждого элемента в массиве, составленном из индекса и значения для того элемента. Можно анализировать кортеж во временные константы или переменные как часть итерации:
for (index, value) in enumerate(shoppingList) {
println("Item \(index + 1): \(value)")
}
// Item 1: Six eggs
// Item 2: Milk
// Item 3: Flour
// Item 4: Baking Powder
// Item 5: Bananas
Для больше о for
-in
цикл, видьте Циклы.
Наборы
Набор хранит отличные значения того же типа в наборе без определенного упорядочивания. Можно использовать наборы в качестве альтернативы массивам, когда порядок пунктов не важен, или когда необходимо гарантировать, что элемент только появляется один раз.
Синтаксис типа набора
Тип набора Swift записан как Set<SomeType>
, где SomeType
тип, который набору позволяют сохранить. В отличие от массивов, наборы не имеют эквивалентной краткой формы.
Создание и инициализация набора
Можно создать пустое множество определенного типа с помощью синтаксиса инициализатора:
var letters = Set<Character>()
println("letters is of type Set<Character> with \(letters.count) items.")
// prints "letters is of type Set<Character> with 0 items."
Обратите внимание на то, что тип letters
переменная выведена, чтобы быть Set<Character>
, от типа инициализатора.
Также, если контекст уже предоставляет информацию типа, такую как аргумент функции или уже переменная определенного типа или постоянный, можно создать пустое множество с литералом пустого массива:
letters.insert("a")
// letters now contains 1 value of type Character
letters = []
// letters is now an empty set, but is still of type Set<Character>
Наборы с литералами массивов
Можно также инициализировать набор с литералом массивов как краткий способ записать одно или более значений как набор набора.
Пример ниже создает вызванный набор favoriteGenres
сохранить String
значения:
var favoriteGenres: Set<String> = ["Rock", "Classical", "Hip hop"]
// favoriteGenres has been initialized with three initial items
favoriteGenres
переменная объявляется как “ряд String
значения”, записанный как Set<String>
. Поскольку этот определенный набор указал тип значения String
, только позволяется сохранить String
значения. Здесь, favoriteGenres
набор инициализируется с три String
значения ("Rock"
, "Classical"
, и "Hip hop"
), записанный в литерале массивов.
Тип набора не может быть выведен из одного только литерала массивов, таким образом, тип Set
должен быть явно объявлен. Однако из-за вывода типа Swift, Вы не должны писать тип набора при инициализации его с литералом массивов, содержащим значения того же типа. Инициализация favoriteGenres
возможно, был записан в более короткой форме вместо этого:
var favoriteGenres: Set = ["Rock", "Classical", "Hip hop"]
Поскольку все значения в литерале массивов имеют тот же тип, Swift может вывести это Set<String>
корректный тип для использования для favoriteGenres
переменная.
Доступ и изменение набора
Вы получаете доступ и изменяете набор через его методы и свойства.
Для обнаружения числа элементов в наборе проверьте его только для чтения count
свойство:
println("I have \(favoriteGenres.count) favorite music genres.")
// prints ""I have 3 favorite music genres.""
Используйте булевскую переменную isEmpty
свойство как ярлык для проверки, ли count
свойство равно 0
:
if favoriteGenres.isEmpty {
println("As far as music goes, I'm not picky.")
} else {
println("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") {
println("\(removedValue)? I'm over it.")
} else {
println("I never much cared for that.")
}
// prints "Rock? I'm over it."
Чтобы проверить, содержит ли набор определенный элемент, используйте contains(_:)
метод.
if favoriteGenres.contains("Funk") {
println("I get up on the good foot.")
} else {
println("It's too funky in here.")
}
// prints "It's too funky in here."
Итерация по набору
Можно выполнить итерации по значениям в наборе с a for
-in
цикл.
for genre in favoriteGenres {
println("\(value)")
}
// Classical
// Jazz
// Hip hop
Для больше о for
-in
цикл, видьте Циклы.
Swift Set
тип не имеет определенного упорядочивания. Для итерации по значениям набора в определенном порядке используйте глобальную переменную sorted
функция, возвращающая упорядоченный набор предоставленной последовательности.
-> for genre in sorted(favoriteGenres) {
println("\(genre)")
}
// prints "Classical"
// prints "Hip hop"
// prints "Jazz"
Выполнение операций присвоения
Можно эффективно выполнить фундаментальные операции присвоения, такие как объединение двух наборов вместе, определение, оценивающее два набора, имеет вместе, или определение, содержат ли два набора все, некоторых или ни одно из тех же значений.
Построение наборов
Иллюстрация ниже изображает два набора –a
и b
– с результатами различных операций присвоения, представленных теневыми областями.
Используйте
union(_:)
метод для создания нового набора со всеми значениями в обоих наборах.Используйте
subtract(_:)
метод для создания нового набора со значениями не в указанном наборе.Используйте
intersect(_:)
метод для создания нового набора с только значениями, характерными для обоих наборов.Используйте
exclusiveOr(_:)
метод для создания нового набора со значениями в любом наборе, но не обоих.
let oddDigits: Set = [1, 3, 5, 7, 9]
let evenDigits: Set = [0, 2, 4, 6, 8]
let singleDigitPrimeNumbers: Set = [2, 3, 5, 7]
sorted(oddDigits.union(evenDigits))
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
sorted(oddDigits.intersect(evenDigits))
// []
sorted(oddDigits.subtract(singleDigitPrimeNumbers))
// [1, 9]
sorted(oddDigits.exclusiveOr(singleDigitPrimeNumbers))
// [1, 2, 9]
Сравнение наборов
Иллюстрация ниже изображает три набора –a
, b
и c
– с перекрывающимися областями, представляющими элементы, совместно используется наборами. Набор a
надмножество набора b
, потому что a
содержит все элементы в b
. С другой стороны, набор b
подмножество набора a
, потому что все элементы в b
также содержатся a
. Набор b
и набор c
являются непересекающимися друг с другом, потому что они не совместно используют элементов вместе.
Используйте, “равный” оператор (
==
) определить, содержат ли два набора все те же значения.Используйте
isSubsetOf(_:)
метод, чтобы определить, содержатся ли все значения набора в указанном наборе, или.Используйте
isSupersetOf(_:)
метод, чтобы определить, содержит ли набор все значения в указанном наборе, или.Используйте
isStrictSubsetOf(_:)
илиisStrictSupersetOf(_:)
методы, чтобы определить, является ли набор подмножеством или надмножеством, но не равный, указанный набор.Используйте
isDisjointWith(_:)
метод, чтобы определить, имеют ли два набора какие-либо значения вместе.
let houseAnimals: Set = [" ", " "]
let farmAnimals: Set = [" ", " ", " ", " ", " "]
let cityAnimals: Set = [" ", " "]
houseAnimals.isSubsetOf(farmAnimals)
// true
farmAnimals.isSuperSetOf(houseAnimals)
// true
farmAnimals.isDisjointWith(cityAnimals)
// true
Значения хэш-функции для типов набора
Тип должен быть hashable для хранения в наборе — т.е. тип должен обеспечить способ вычислить значение хэш-функции для себя. Значение хэш-функции Int
значение, которое является тем же для всех объектов, выдерживающих сравнение равный, такой что если a == b
, из этого следует, что a.hashValue == b.hashValue
.
Все основные типы Swift (такой как String
, Int
, Double
, и Bool
) hashable по умолчанию и может использоваться в качестве типов значения набора или ключевых типов словаря. Задействованные значения перечисления без присваиваемых значений (как описано в Перечислениях) также hashable по умолчанию.
Словари
Словарь хранит ассоциации между ключами того же типа и значениями того же типа в наборе без определенного упорядочивания. Каждое значение связано с уникальным ключом, действующим как идентификатор для того значения в словаре. В отличие от элементов в массиве, элементы в словаре не имеют указанного порядка. Вы используете словарь, когда необходимо искать значения на основе их идентификатора почти таким же способом, которым реальный словарь используется для поиска определения для определенного слова.
Краткий синтаксис типа словаря
Тип словаря Swift записан полностью как Dictionary<Key, Value>
, где Key
тип имеющий значение, который может использоваться в качестве ключа словаря, и Value
тип имеющий значение, который словарь хранит для тех ключей.
Можно также записать тип словаря в краткой форме как [Key: Value]
. Несмотря на то, что две формы функционально идентичны, краткая форма предпочтена и используется всюду по этому руководству при обращении к типу словаря.
Создание пустого словаря
Как с массивами, можно создать пустое Dictionary
из определенного типа при помощи синтаксиса инициализатора:
var namesOfIntegers = [Int: String]()
// namesOfIntegers is an empty [Int: String] dictionary
Этот пример создает пустой словарь типа [Int: String]
сохранить человекочитаемые имена целочисленных значений. Его ключи имеют тип Int
, и его значения имеют тип String
.
Если контекст уже предоставляет информацию типа, можно создать пустой словарь с пустым литералом словаря, записанным как [:]
(двоеточие в паре квадратных скобок):
namesOfIntegers[16] = "sixteen"
// namesOfIntegers now contains 1 key-value pair
namesOfIntegers = [:]
// namesOfIntegers is once again an empty dictionary of type [Int: String]
Литералы словаря
Можно также инициализировать словарь с литералом словаря, имеющим подобный синтаксис к литералу массивов, замеченному ранее. Литерал словаря является кратким способом записать одну или более пар ключ/значение как a Dictionary
набор.
Пара ключ/значение является комбинацией ключа и значения. В литерале словаря ключ и значение в каждой паре ключ/значение разделяются двоеточием. Пары ключ/значение записаны как список, разделенный запятыми, окруженными парой квадратных скобок:
[key 1: value 1, key 2: value 2, key 3: value 3]
Пример ниже создает словарь для хранения имен международных аэропортов. В этом словаре ключи являются Международными кодами Ассоциации Воздушного транспорта с тремя буквами, и значения являются именами аэропорта:
var airports: [String: String] = ["YYZ": "Toronto Pearson", "DUB": "Dublin"]
airports
словарь объявляется как наличие типа [String: String]
, что означает “a Dictionary
чьи ключи имеют тип String
, и чьи значения имеют также тип String
”.
airports
словарь инициализируется с литералом словаря, содержащим две пары ключ/значение. Первая пара имеет ключ "YYZ"
и значение "Toronto Pearson"
. Вторая пара имеет ключ "DUB"
и значение "Dublin"
.
Этот литерал словаря содержит два String: String
пары. Этот тип значения ключа соответствует тип airports
объявление переменной (словарь с только String
ключи, и только String
значения), и таким образом, присвоение литерала словаря разрешено как способ инициализировать airports
словарь с двумя начальными элементами.
Как с массивами, Вы не должны писать тип словаря при инициализации его с литералом словаря, ключи которого и значения имеют непротиворечивые типы. Инициализация airports
возможно, был быть записанным в более короткой форме вместо этого:
var airports = ["YYZ": "Toronto Pearson", "DUB": "Dublin"]
Поскольку все ключи в литерале имеют тот же тип друг как друг, и аналогично все значения имеют тот же тип друг как друг, Swift может вывести это [String: String]
корректный тип для использования для airports
словарь.
Доступ и изменение словаря
Вы получаете доступ и изменяете словарь через его методы и свойства, или при помощи нижнего синтаксиса. Как с массивом, Вы узнаете число элементов в a Dictionary
путем проверки его только для чтения count
свойство:
println("The airports dictionary contains \(airports.count) items.")
// prints "The airports dictionary contains 2 items."
Используйте булевскую переменную isEmpty
свойство как ярлык для проверки, ли count
свойство равно 0
:
if airports.isEmpty {
println("The airports dictionary is empty.")
} else {
println("The airports dictionary is not empty.")
}
// prints "The airports dictionary is not empty."
Можно добавить новый элемент к словарю с нижним синтаксисом. Используйте новый ключ надлежащего типа как нижний индекс и присвойте новое значение надлежащего типа:
airports["LHR"] = "London"
// the airports dictionary now contains 3 items
Можно также использовать нижний синтаксис для изменения значения, связанного с определенным ключом:
airports["LHR"] = "London Heathrow"
// the value for "LHR" has been changed to "London Heathrow"
Как альтернатива преобразованию в нижний индекс, используйте словарь updateValue(_:forKey:)
метод, чтобы установить или обновить значение для определенного ключа. Как нижние примеры выше, updateValue(_:forKey:)
метод устанавливает значение для ключа, если ни один не существует или обновляет значение, если уже существует тот ключ. В отличие от нижнего индекса, однако, updateValue(_:forKey:)
метод возвращает старое значение после выполнения обновления. Это позволяет Вам проверить, имело ли обновление место.
updateValue(_:forKey:)
метод возвращает дополнительное значение типа значения словаря. Для хранящего словаря String
значения, например, метод возвращает значение типа String?
, или “дополнительный String
”. Если один существовал перед обновлением, или, это дополнительное значение содержит старое значение для того ключа nil
если не существовало никакое значение:
if let oldValue = airports.updateValue("Dublin Airport", forKey: "DUB") {
println("The old value for DUB was \(oldValue).")
}
// prints "The old value for DUB was Dublin."
Можно также использовать нижний синтаксис для получения значения из словаря для определенного ключа. Поскольку возможно запросить ключ, для которого не существует никакое значение, нижний индекс словаря возвращает дополнительное значение типа значения словаря. Если словарь содержит значение для требуемого ключа, нижний индекс возвращает дополнительное значение, содержащее существующее значение для того ключа. Иначе, нижние возвраты nil
:
if let airportName = airports["DUB"] {
println("The name of the airport is \(airportName).")
} else {
println("That airport is not in the airports dictionary.")
}
// prints "The name of the airport is Dublin Airport."
Можно использовать нижний синтаксис для удаления пары ключ/значение из словаря путем присвоения значения nil
для того ключа:
airports["APL"] = "Apple International"
// "Apple International" is not the real airport for APL, so delete it
airports["APL"] = nil
// APL has now been removed from the dictionary
Также удалите пару ключ/значение из словаря с removeValueForKey(_:)
метод. Этот метод удаляет пару ключ/значение, если это существует и возвращает удаленное значение или возвраты nil
если не существовало никакое значение:
if let removedValue = airports.removeValueForKey("DUB") {
println("The removed airport's name is \(removedValue).")
} else {
println("The airports dictionary does not contain a value for DUB.")
}
// prints "The removed airport's name is Dublin Airport."
Итерация по словарю
Можно выполнить итерации по парам ключ/значение в словаре с a for
-in
цикл. Каждый элемент в словаре возвращается как a (key, value)
кортеж, и можно анализировать элементы кортежа во временные константы или переменные как часть итерации:
for (airportCode, airportName) in airports {
println("\(airportCode): \(airportName)")
}
// YYZ: Toronto Pearson
// LHR: London Heathrow
Для больше о for
-in
цикл, видьте Циклы.
Можно также получить повторяемый набор ключей словаря или значений путем доступа к keys
и values
свойства:
for airportCode in airports.keys {
println("Airport code: \(airportCode)")
}
// Airport code: YYZ
// Airport code: LHR
for airportName in airports.values {
println("Airport name: \(airportName)")
}
// Airport name: Toronto Pearson
// Airport name: London Heathrow
Если необходимо использовать ключи словаря или значения с API, берущим Array
экземпляр, инициализируйте новый массив с keys
или values
свойство:
let airportCodes = [String](airports.keys)
// airportCodes is ["YYZ", "LHR"]
let airportNames = [String](airports.values)
// airportNames is ["Toronto Pearson", "London Heathrow"]
Swift Dictionary
тип не имеет определенного упорядочивания. Для итерации по ключам или значениям словаря в определенном порядке используйте глобальную переменную sorted
функция на keys
или values
свойство.