Получить несколько значений по одному ключу в словаре
Есть некий словарь:
Dictionary<string, string> AuthorList = new Dictionary<string, string>();
AuthorList.Add("aaa", "гистидин");
AuthorList.Add("bbb", "фенилаланин");
AuthorList.Add("aaa", "кокаин");
AuthorList.Add("ccc", "глицин");
AuthorList.Add("ddd", "глицин");
AuthorList.Add("aaa", "атропин");
Как мне по ключу aaa получить все значения (в виде списка или массива)?
Ответы (3 шт):
Значения для каждого ключа хранятся в List, поэтому могут повторяться:
Dictionary<string, List<string>> AuthorDict = new Dictionary<string, List<string>>();
AuthorDict["aaa"] = new List<string>();
AuthorDict["bbb"] = new List<string>();
AuthorDict["ccc"] = new List<string>();
AuthorDict["aaa"].Add("1");
AuthorDict["bbb"].Add("2");
AuthorDict["aaa"].Add("3");
AuthorDict["ccc"].Add("4");
AuthorDict["bbb"].Add("2");
foreach (var item in AuthorDict)
Console.WriteLine($"{item.Key}: {String.Join(", ", item.Value)}");
Вывод:
aaa: 1, 3
bbb: 2, 2
ccc: 4
Значения для каждого ключа хранятся в HashSet, поэтому будут уникальными:
Dictionary<string, HashSet<string>> AuthorDict = new Dictionary<string, HashSet<string>>();
AuthorDict["aaa"] = new HashSet<string>();
AuthorDict["bbb"] = new HashSet<string>();
AuthorDict["ccc"] = new HashSet<string>();
AuthorDict["aaa"].Add("1");
AuthorDict["bbb"].Add("2");
AuthorDict["aaa"].Add("3");
AuthorDict["ccc"].Add("4");
AuthorDict["bbb"].Add("2");
foreach (var item in AuthorDict)
Console.WriteLine($"{item.Key}: {String.Join(", ", item.Value)}");
Вывод:
aaa: 1, 3
bbb: 2
ccc: 4
Почему не работает у вас
Так как ваш AuthorList имеет тип данных Dictionary<string, string>, то он состоит из пар KeyValuePair, где ключ - строка, и значение - строка. Таким образом, когда вы несколько раз записываете значения в ячейку с одним и тем же ключом, старое просто стирается (как в обычной переменной). Пример:
Dictionary<string, string> dict = new Dictionary<string, string>();
dict["Key1"] = "Value1";
Console.WriteLine(dict["Key1"]);
dict["Key1"] = "Value2";
Console.WriteLine(dict["Key1"]);
dict["Key1"] = "Value3";
Console.WriteLine(dict["Key1"]);
Вывод:
Value1
Value2
Value3
Что делать?
Если вы хотите хранить сразу несколько значений для каждого ключа, ваш выбор - List.
В таком случае словарь будет создаваться таким образом:
Dictionary<string, List<string>> dict = new Dictionary<string, List<string>>();
Конкретно вашу задачу можно реализовать следующим образом:
Dictionary<string, List<string>> AuthorDict = new Dictionary<string, List<string>>();
AuthorDict["aaa"] = new List<string>();
AuthorDict["bbb"] = new List<string>();
AuthorDict["ccc"] = new List<string>();
AuthorList["aaa"].Add("гистидин");
AuthorList["bbb"].Add("фенилаланин");
AuthorList["aaa"].Add("кокаин");
AuthorList["ccc"].Add("глицин");
AuthorList["ddd"].Add("глицин");
AuthorList["ddd"].Add("атропин");
В дальнейшем вы можете обращаться к списку значений или к определенному значению по ключу следующим образом:
AuthorList["bbb"]; // Список по ключу "bbb"
AuthorList["aaa"][1]; // Первый элемент из списка по ключу "aaa"
Дополнительно
В целом словарь представляет собой структуру KeyValuePair<TKey, TValue>, то есть и ключом, и значением может быть вообще любой тип данных. Поэтому в зависимости от ваших желаний и целей, вы можете использовать и очереди Queue, чтобы иметь возможности очередей, и хешсет HashSet, и даже другой словарь Dictionary. Например:
Dictionary<string, Queue<string>> QueuedDictionary = new Dictionary<string, Queue<string>>();
Dictionary<string, HashSet<string>> HashsetDictionary = new Dictionary<string, HashSet<string>>();
Dictionary<string, Dictionary<int, string>> DoubleDictionary = new Dictionary<string, Dictionary<int, string>>();
Все это можно назвать List'ами с дополнительными особенностями, но т.к. вы в своем вопросе их не упоминали, на этом эту тему я остановлю
P.S. Как мне по ключу aaa получить все значения (в виде списка или массива)? - с массивом реализовать это будет сложно, так как его длина не динамична, поэтому могут возникнуть сложности с инициализацией или чтением...
Вам нужен словарь, который по одному ключу может хранить несколько разных значений. Такие словари обычно называются как-то наподобие MultiDictionary.
К примеру, можно взять майкрософтовский MultiValueDictionary из nuget-пакета Microsoft.Experimental.Collections (осторожно, он пре-релизный!). Подключите пакет (вам придётся поставить галку Include prerelease), и ваш код станет просто таким:
MultiValueDictionary<string, string> AuthorList = new();
AuthorList.Add("aaa", "гистидин");
AuthorList.Add("bbb", "фенилаланин");
AuthorList.Add("aaa", "кокаин");
AuthorList.Add("ccc", "глицин");
AuthorList.Add("ddd", "глицин");
AuthorList.Add("aaa", "атропин");
var results = AuthorList["aaa"];
foreach (var result in results)
Console.WriteLine(result);
На консоли
гистидин
кокаин
атропин