Словарь Dictionary<T, V>
Еще один распространенный тип коллекции представляют словари. Словарь хранит объекты, которые представляют пару ключ-значение. Класс словаря Dictionary<K, V> типизируется двумя типами: параметр K представляет тип ключей, а параметр V предоставляет тип значений.
Создания и инициализация словаря
Класс Dictionary предоставляет ряд конструкторов для создания словаря. Например, мы можем создать пустой словарь:
Dictionary<int, string> people = new Dictionary<int, string>();
Здесь словарь people в качестве ключей принимает значения типа int, а в качестве значений - строки.
При определении словаря его сразу же можно инициализировать значениями:
var people = new Dictionary<int, string>()
{
{ 5, "Tom"},
{ 3, "Sam"},
{ 11, "Bob"}
};
При инициализации применяется инициализитор - в фигурных скобках после вызова конструктора объекту передаются начальные данные. В случае со словаем мы можем передать в инициализаторе набор элементов, где каждый элемент заключается в фигурные скобки, например:
{ 5, "Tom"}
Каждый элемент представляет два значения: первое значение представляет ключ, а второе значение - собственно значение элемента. Поскольку при объявлении словаря people для ключей указан тип int, а для значений - тип string, то в элементе словаря сначала указывается число int, а затем строка. То есть в случае выше элемент имеет ключ 5, а значение - "Tom". Затем по ключу элемента мы сможем получить его значение.
Также мы можем применять другой способ инициализации:
var people = new Dictionary<int, string>()
{
[5] = "Tom",
[6] = "Sam",
[7] = "Bob"
};
При таком способе инициализации в квадратных скобках указывается ключ и ему присваивается значение элемента. Но в целом этот способ инициализации будет равноценен предыдущему.
KeyValuePair
Стоит отметить, что каждый элемент в словаре представляет структуру KeyValuePair<TKey, TValue>, где параметр TKey представляет тип ключа, а параметр TValue - тип значений элементов. Эта структура предоставляет свойства Key и Value, с помощью которых можно получить соответственно ключ и значение элемента в словаре. И одна из версий конструктора Dictionary позволяет инициализировать словарь коллекцией объектов KeyValuePair:
var mike = new KeyValuePair<int, string>(56, "Mike");
var employees = new List<KeyValuePair<int, string>>() { mike};
var people = new Dictionary<int, string>(employees);
Конструктор типа KeyValuePair принимает два параметра - ключ элемента и его значения. То есть в данном случае создается один такой элемент - mike с ключом 56 и значением "Mike". И этот элемент добавляется в список employees, которым затем инициализируется словарь.
Можно совместить оба способа инициализации:
var mike = new KeyValuePair<int, string>(56, "Mike");
var employees = new List<KeyValuePair<int, string>>() { mike };
var people = new Dictionary<int, string>(employees)
{
[5] = "Tom",
[6] = "Sam",
[7] = "Bob",
};
В данном случае в словаре people будет четыре элемента.
Перебор словаря
Для перебора словаря можно применять цикл foreach:
var people = new Dictionary<int, string>()
{
[5] = "Tom",
[6] = "Sam",
[7] = "Bob"
};
foreach(var person in people)
{
Console.WriteLine($"key: {person.Key} value: {person.Value}");
}
При переборе каждый элемент будет помещаться в переменную, которая представляет тип KeyValuePair, соответственно с помощью свойств Key и Value мы сможем получить ключ и значение элемента. Консольный вывод программы:
key: 5 value: Tom
key: 6 value: Sam
key: 7 value: Bob
Получение элементов
Для обращения к элементам из словаря применяется их ключ, который передается в квадратных скобках:
словарь[ключ]
Таким образом мы можем получить и изменить элементы словаря
var people = new Dictionary<int, string>()
{
[5] = "Tom",
[6] = "Sam",
[7] = "Bob",
};
// получаем элемент по ключу 6
string sam = people[6]; // Sam
Console.WriteLine(sam); // Sam
// переустанавливаем значение по ключу 6
people[6] = "Mike";
Console.WriteLine(people[6]); // Mike
// добавляем новый элемент по ключу 22
people[22] = "Eugene";
Console.WriteLine(people[22]); // Eugene
Более того, таким образом мы можем также добавить новый элемент в словарь. При установке значения по ключу, если элемент с таким ключом уже есть в словаре, то значение переустанавливается. Если же элемента с подобным ключом нет в словаре, то элемент добавляется.:
Методы и свойства Dictionary
Среди методов класса Dictionary можно выделить следующие:
void Add(K key, V value): добавляет новый элемент в словарь
void Clear(): очищает словарь
bool ContainsKey(K key): проверяет наличие элемента с определенным ключом и возвращает true при его наличии в словаре
bool ContainsValue(V value): проверяет наличие элемента с определенным значением и возвращает true при его наличии в словаре
bool Remove(K key): удаляет по ключу элемент из словаря
Другая версия этого метода позволяет получить удленный элемент в выходной параметр: bool Remove(K key, out V value)
bool TryGetValue(K key, out V value): получает из словаря элемент по ключу key. При успешном получении передает значение элемента в выходной параметр value и возвращает true
bool TryAdd(K key, V value): добавляет в словарь элемент с ключом key и значением value. При успешном добавлении возвращает true
Из свойств следует отметить свойство Count, которое возвращает количество элементов в словаре.
Применение методов:
// условная телефонная книга
var phoneBook = new Dictionary<string, string>();
// добавляем элемент: ключ - номер телефона, значение - имя абонента
phoneBook.Add("+123456", "Tom");
// альтернативное добавление
// phoneBook["+123456"] = "Tom";
// Проверка наличия
var phoneExists1 = phoneBook.ContainsKey("+123456"); // true
Console.WriteLine($"+123456: {phoneExists1}");
var phoneExists2 = phoneBook.ContainsKey("+567456"); // false
Console.WriteLine($"+567456: {phoneExists2}");
var abonentExists1 = phoneBook.ContainsValue("Tom"); // true
Console.WriteLine($"Tom: {abonentExists1}");
var abonentExists2 = phoneBook.ContainsValue("Bob"); // false
Console.WriteLine($"Bob: {abonentExists2}");
// удаление элемента