Словари (Dictionary) в Swift

Домашняя работа к главе 11

Словарь — это неупорядоченная коллекция элементов, для доступа к значениям которых используются специальные индексы, называемые ключами. Каждый элемент словаря состоит из уникального ключа, указывающего на данный элемент, и значения. В качестве ключа выступает не автоматически генерируемый целочисленный индекс (как в массивах), а уникальное для словаря значение произвольного типа, определяемое программистом. Чаще всего в качестве ключей используются строковые или целочисленные значения. Все ключи словаря должны быть единого типа данных. То же относится и к значениям.

Задание 1

В результате каких из выражений будет создан словарь? Какой тип данных будет у созданных параметров?

var dict1: Dictionary = ["One":(100,101),"Two":(200,201)]
var dict2: Dictionary = [(1,2,3):1, (2,3,4):2]
var dict3: Dictionary<Int,Int> = [1:13.3, 2:14.1, 3: 16.9]
var dict4 = Dictionary(uniqueKeysWithValues: [(1,2), (3,4), (5,6)])
var dict5 = ["Alex": 1989, "John": 2002, "Harold": 1951]
var dict6: Dictionary = [1, 2, 3, 4]
Правильный ответ

dict1 — словарь
type(of:dict1) // Dictionary<String, (Int, Int)>.Type
dict2 — ошибка
Ключ словаря должен быть Hashable (хэшируемым), а кортежи не являются Hashable.
dict3 — ошибка
Тип значений элементов указанный явно, отличается от типа переданных значений (Int и Double)
dict4 — словарь
type(of:dict4) // Dictionary<Int, Int>.Type
dict5 — словарь
type(of:dict5) // Dictionary<String, Int>.Type
dict6 — ошибка
В качестве значения передан литерал массива, а не литерал словаря

 

Задание 2

1) Какой тип будет иметь словарь, ключи элементов которого будут строковыми значениями (String), а значения элементов — символьными (Character)
2) Покажите все известные вам способы создания словаря такого типа. Экспериментируйте, вполне вероятно мы с вами можем ответить на данный вопрос разными способами.

Правильный ответ

// 1) 
Dictionary<String,Character>
// 2) 
// По большому счету можно выделить два основных способа
// первый - когда тип элементов указывается явно
// второй - когда тип элементов указывается неявно
// Но для каждого из указанных способов можно показать большое количество отличающихся примеров, использующих те или иные механизмы

// способ 1. С помощью явного указания типа
// через передачу литерала
var strDict1: Dictionary<String, Character> = ["name": "V", "surname": "U"]
type(of: strDict1) // Dictionary<String, Character>.Type
// с помощью Dictionary(dictionaryLiteral:)
var strDict2: Dictionary<String, Character> = Dictionary(dictionaryLiteral: ("lang", "R"), ("encode", "U"))
type(of: strDict2) // Dictionary<String, Character>.Type

//способ 2. С помощью неявного указания типа
// через передачу литера
var strDict3 = ["name":Character("V"), "surname":Character("U")]
type(of: strDict3) // Dictionary<String, Character>.Type
// с помощью Dictionary(dictionaryLiteral:)
var strDict4 = Dictionary(dictionaryLiteral: ("lang", Character("R")), ("encode", Character("U")))
type(of: strDict4) // Dictionary<String, Character>.Type

Доступ закрыт

Дополнительные 3 задания доступны только подписчикам

Оформить доступ


6 Comments

  1. ageres7:

    Пожалуйста помогите понять, почему в задании 4 невозможно выполнить пункт 4? Ведь можно же создать например набор [«100″,»USA», «101», «CAN», «102», «MEX»] типа Set<String> . Почему и тут не привести taskSet и taskArr  к типу  Set<String> ?

    • krovevs:

      Как я понял — массив можно преобразовать в набор, и наоборот. Но вот тип содержащихся внутри элементов нет. А в 4 пункте как раз и выходит что нужно создать набор передав ему конкатенацию элементов INT из набора и элементов STRING из массива. Само преобразование в SET\ARRAY работает, а вот генерик в увы нет.

      • antokhin.aleksey:

        На данном этапе главы(изучения) такой возможности нет. Но что бы преобразовать тип элемента внутри коллекции, нужно создать новую коллекцию проинициализировав ей например следующее замыкание: let set3 = Set(set1.map{String($0)}). Функции высшего порядка такие как .map, .filter, reduce хорошо описаны в главе 17 пятого издания книги Василия Усова:)

  2. qgusein:

    Может сможет кто объяснить. Создайте массив, состоящий из dictElCount одинаковых элементов, значений которых dictElCount. Какой тип данных будет у созданного массива?Не понял решение этого пункта. 

    • antokhin.aleksey:

      «Создайте массив, состоящий из dictElCount одинаковых элементов» — т.е. массив будет из констант dictElCount. Здесь dictElCount.count это простой Int число.
      «значений которых dictElCount» — т.е. количество элементов результирующего массива = значению константы dictElCount. Например в ответе в исходном массиве superDict: 2 элемента соответственно в результирующем массиве arrayFromDict тоже будет 2 элемента.
      Тип любого массива определяется типом его элементов. Все элементы в массиве одного типа.
      Если у Вас массив из Int элементов то тип массива будет [Int].

      Вроде так:)

  3. antokhin.aleksey:

    Добрый день.

    У задания №4 п.4 на мой взгляд есть решение через .map:

    //1
    let dictionary5:Dictionary = [1:»status», 0:»error», 5:»responce»]
    //2
    let set1 = Set(dictionary5.keys)
    type(of: set1)
    let set3 = Set(set1.map{String($0)})
    type(of: set3)
    print(set3)
    //3
    let array1 = Array(dictionary5.values)
    type(of: array1)
    print(array1)
    //4
    let set2 = set3.union(Set(array1))
    print(set2)
    type(of: set2)

    Спасибо.

Добавить комментарий