Как найти предмет в коллекции словарей?
Я объявил и заполнил следующую коллекцию.
protected static Dictionary<string, string> _tags;
Теперь я хочу посмотреть местонахождение определенной записи в коллекции. Я попробовал следующее.
thisTag = _tags.FirstOrDefault(t => t.Key == tag);
if (thisTag != default(KeyValuePair<string, string>))
...
И я получаю сообщение об ошибке:
Оператор '! =' не может применяться к операндам типа 'System.Collections.Generic.KeyValuePair' и ''
Сначала я попытался сравнить результат с null
, и я думаю, что это не поддерживается с помощью struct
s.
Я бы подумал, что найти элемент в коллекции - очень тривиальная задача. Итак, как я могу определить, найден ли элемент, который я ищу?
(Примечание: я использую Dictionary
, потому что я хочу быстрый поиск. Я знаю, что могу использовать Contains()
, чтобы определить, есть ли элемент. Но это означает, что в общей сложности два поиска, которые видят поражение цели быстрый просмотр. Я с удовольствием использую другую коллекцию, если она сможет быстро найти элемент, и у меня есть способ определить, было ли это успешным.)
Ответы
Ответ 1
thisTag = _tags.FirstOrDefault(t => t.Key == tag);
является неэффективным и немного странным способом найти что-то по ключевому слову в словаре. Взгляд на ключ - основная функция Словаря.
Основным решением будет:
if (_tags.Containskey(tag)) { string myValue = _tags[tag]; ... }
Но для этого требуется 2 поиска.
TryGetValue(key, out value)
более краткий и эффективный, он выполняет только 1 поиск. И это отвечает на последнюю часть вашего вопроса, лучший способ выполнить поиск:
string myValue;
if (_tags.TryGetValue(tag, out myValue)) { /* use myValue */ }
VS 2017, для С# 7 и далее мы можем объявить переменную result inline:
if (_tags.TryGetValue(tag, out string myValue))
{
// use myValue;
}
// use myValue, still in scope, null if not found
Ответ 2
Иногда вам все равно нужно использовать FirstOrDefault, если вам нужно делать разные тесты.
Вы можете сделать это так:
thisTag = _tags.FirstOrDefault(t => t.Key.SubString(1,1) == 'a');
if(thisTag.Key != null) { ... }
Используя FirstOrDefault, возвращаемый ключ KeyValuePair и значение будут равны нулю, если совпадение не найдено.
Ответ 3
Конечно, если вы хотите убедиться, что в противном случае это не срабатывает, это работает:
thisTag = _tags [key];
ПРИМЕЧАНИЕ. Это произойдет, если пара ключей, значений не существует, но иногда это именно то, что вы хотите.
Таким образом вы можете поймать его и сделать что-то об ошибке.
Я бы сделал это только в том случае, если я уверен, что пара ключей, значений или должна быть в словаре, и если я не хочу, чтобы он знал об этом через бросок.
Ответ 4
Можно найти элемент в коллекции Словаря, используя ContainsKey или TryGetValue следующим образом:
class Program
{
protected static Dictionary<string, string> _tags = new Dictionary<string,string>();
static void Main(string[] args)
{
string strValue;
_tags.Add("101", "C#");
_tags.Add("102", "ASP.NET");
if (_tags.ContainsKey("101"))
{
strValue = _tags["101"];
Console.WriteLine(strValue);
}
if (_tags.TryGetValue("101", out strValue))
{
Console.WriteLine(strValue);
}
}
}