TOC

This article has been localized into Russian by the community.

Коллекции:

Словари

Все словари в C# реализуют Интерфейс IDictionary. Существует несколько типов словарей, но наиболее часто используется Универсальный словарь, часто называемый Dictionary<TKey, TValue> - содержит ключ определенного типа и соответствующее значение конкретного типа. Это в основном то, что отличает словарь от списка-элементов, приходящих в определенном порядке и доступных с помощью числового индекса, где элементы в словаре хранятся с уникальным ключом, который затем может быть использован для повторного получения элемента.

Мы подробнее рассмотрим, что такое словари, но сначала давайте рассмотрим простой пример, чтобы показать вам, что это такое:

Dictionary<string, int> users = new Dictionary<string, int>();  
users.Add("John Doe", 42);  
users.Add("Jane Doe", 38);  
users.Add("Joe Doe", 12);  
users.Add("Jenna Doe", 12);

Console.WriteLine("John Doe is " + users["John Doe"] + " years old");

Познакомьтесь с семейством Doe, которое является тестовыми данными для примера в этом учебнике. Папа, мама и близнецы Джо и Дженна. Обратите внимание, как я определяю словарь, чтобы использовать строку в качестве ключа (в этом случае имя) и целое число для значения (в этом случае возраст). Самое классное, что это позволяет нам получить доступ к элементу из словаря, используя ключ (имя), а не числовой индекс. Вы можете видеть, что в действии в последней строке примера-между набором квадратных скобок, мы просто указываем ключ, для доступа к значению (возрасту).

Здесь важно знать две вещи: во-первых, ключ должен быть уникальным. В этом случае, когда мы используем строку в качестве ключа, это означает, что вы не можете добавить два пользователя с таким же именем. Это имеет смысл, потому что когда вы можете использовать ключ для ссылки на один элемент, ключ может указывать только на одно значение. С другой стороны, это делает этот пример слишком простым, потому что, очевидно, у вас не может быть коллекции пользователей, где дубликаты имен не могут существовать, но пока проявите терпение.

Другая вещь, которую вы должны будете помнить, при доступе к значениям из словаря, заключается в том, что ключ должен существовать в коллекции, когда вы пытаетесь получить доступ к его значению. Другими словами, мой пример был безопасен только потому, что я полностью контролировал то, что содержал список - в большинстве ситуаций вы всегда должны проверять, существует ли ключ, прежде чем пытаться использовать его - например:

string key = "John Doe";
if(users.ContainsKey(key))
    Console.WriteLine("John Doe is " + users[key] + " years old");

При попытке добавить ключ, который уже существует, или при попытке доступа к значению с ключом, который не существует, .NET выдаст исключение. Это может показаться очевидным, но на самом деле очень часто встречаются в перечнях исключений по всему миру.

Работа с элементами

Доступ к одному элементу может быть очень полезен, но что, если вы хотите циклически просматривать коллекцию и, например, искать что-то? В этом случае первое, что вы должны знать, это то, что элементы в списке, очевидно, не просто объект - вместо этого словарь содержит элементы типа KeyValuePair<TKey, TValue>. T-это типы, которые Вы использовали для объявления списка-в этом случае строка и целое число. Таким образом, цикл по коллекции с циклом foreach будет выглядеть примерно так:

Dictionary<string, int> users = new Dictionary<string, int>()
{
    { "John Doe", 42 },
    { "Jane Doe", 38 },
    { "Joe Doe", 12 },
    { "Jenna Doe", 12 }
};
foreach (KeyValuePair<string, int> user in users)
{
    Console.WriteLine(user.Key + " is " + user.Value + " years old");
}

Первое, что вы можете заметить, это то, что я использовал возможность изменить способ инициализации словаря - вместо того, чтобы вручную добавлять каждый элемент после создания экземпляра словаря, мы используем синтаксис инициализатора коллекции, как описано в предыдущей статье.

Теперь у нас есть тот же словарь, что и раньше - давайте пройдемся по нему. Как вы можете видеть, я использую цикл foreach, и я объявил Тип элемента, который я ожидаю как строку KeyValuePair, int & gt; - точно такие же два типа, используемые для объявления словаря. Теперь мы можем получить доступ как к ключу, так и к значению (имени и возрасту) для каждого элемента, и мы используем это для создания простой строки информации о человеке на консоли.

Очередность элементов

Приведенный выше пример подводит нас к очень важному моменту: в отличие от списка, где основной порядок элементов определяется числовыми индексами, порядок элементов в словаре недетерминирован - вы просто не можете полагаться на элементы, находящиеся в определенном порядке, даже если вы вручную добавляете каждый элемент по отдельности. Конечно, когда вы запустите приведенный выше пример, вы, вероятно, почувствуете, что элементы находятся в том же порядке, что и мы их добавили, но это не гарантируется, и как только у вас есть словарь с большим количеством элементов и начать добавлять и удалять элементы, порядок, скорее всего, изменится.

Класс Dictionary не поставляется с методом Sort (), потому что в конце концов, даже если вы отсортируете его, порядок может измениться, как только вы начнете работать с ним снова. Вместо этого можно использовать методы OrderBy() и OrderByDescending() из LINQ (подробнее об этом в другой главе) для получения отсортированной копии словаря. Это также позволяет Сортировать по ключу или по значению, что может быть полезно в нашем примере, чтобы вывести пользователей в порядке их возраста:

Dictionary<string, int> users = new Dictionary<string, int>()
{
    { "John Doe", 42 },
    { "Jane Doe", 38 },
    { "Joe Doe", 12 },
    { "Jenna Doe", 12 }
};
foreach (KeyValuePair<string, int> user in users.OrderBy(user => user.Value))
{
    Console.WriteLine(user.Key + " is " + user.Value + " years old");
}

Если вы запустите пример, вы увидите, что хотя словарь объявлен с элементами в одном порядке, мы можем легко получить их в другом порядке, как мы считаем нужным. Просто помните, что вы несете ответственность за обеспечение получения элементов в нужном порядке, поскольку .NET framework сохраняет их точно так, как считает нужным.


This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!