Подтвердить что ты не робот

Как найти предмет в коллекции словарей?

Я объявил и заполнил следующую коллекцию.

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(), чтобы определить, есть ли элемент. Но это означает, что в общей сложности два поиска, которые видят поражение цели быстрый просмотр. Я с удовольствием использую другую коллекцию, если она сможет быстро найти элемент, и у меня есть способ определить, было ли это успешным.)

4b9b3361

Ответ 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);
        }
    }
}