2015-03-23 2 views
-1

У меня есть список словарей, и я ищу ключ, основанный на значении. Как это сделать?получение ключа, когда значение известно в словаре

"someId" возвращает ошибку:

"The given key was not present in the dictionary."

Так что, если я даю значение «Ann», то я бы ожидать, что функция возвращала ключ «30».

Каждый элемент в словаре, как это

item 1 
    [0] {[someid,30]} 
    [1] {[somename,"Ann"]} 
    [2] {[someaddress,"3, Carl House, UK"]} 


private static int getmyId(string name) 
{ 
    ... 
    List<Dictionary<string, string>> myList = new List<Dictionary<string, string>>(); 

    foreach (Dictionary<string, string> item in myList) 
    {   
     if (item.ContainsValue(name)) 
     { 
       myID = item["Someid"]; 
     } 
    } 
    ... 
    return myID 
} 
+2

Функция, которую вы опубликовали, ничего не возвращает. Кроме того, это даже не имеет смысла. Вы забыли включить все это? – JNYRanger

+0

Почему вы выполняете 'string x = item [" SomeName "];' во всех словарях? –

+0

@ user1651888 Это не похоже на элегантное решение проблемы. Если вы предоставите более подробную информацию о том, что вы пытаетесь достичь, мы можем помочь найти лучшее решение. – TheLukeMcCarthy

ответ

2

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

Вот оба метода как статические функции:

static List<string> GetKeysFromValue(Dictionary<string,string> dict, string val) 
{ 
    if(!dict.ContainsValue(val)) 
     return new List<string>(); //return EMPTY list for no matching keys 

    return dict.Where(kv => kv.Value.Equals(val)).Select(kv => kv.Key).ToList(); 
} 

Для объяснения выше:

  1. Мы получаем все пары ключ-значение в словаре, которые имеют соответствующее значение с помощью функции Where LinQ ,
  2. Теперь, когда у нас есть IEnumerable объектов KeyValuePair, тогда мы вызываем Select, что является функцией linq, которая выполняет проекции. Это отбирает ключи из возвращаемого IEnumerable<KeyValuePair>.
  3. Наконец, мы сводим IEnumerable<string> в список по телефону .ToList()

Чтобы получить только первый соответствующий ключ, вы можете сделать это:

static string GetFirstKeyFromValue(Dictionary<string,string> dict, string val) 
{ 
    if(!dict.ContainsValue(val)) 
     return null; //return null because nothing matched. 

    return dict.FirstOrDefault(kv => kv.Value.Equals(val)).Key; 
} 

FirstOrDefault возвращает первую подходящую пару ключ значение из словаря, или null, если ни один не найден. Поскольку мы уже проверили, что он вернет что-то раньше с помощью метода ContainsValue(), мы можем просто позвонить Key, чтобы получить значение свойства ключа.

Я также хотел указать, что на основании вашей подписи метода, которую вы опубликовали, вы обрабатываете Dictionary<string,string> как List<string>. Словарь не имеет индексов, поэтому используется определенный пользователем тип ключа. Поэтому нет причин возвращать int, так как нет индекса. Вместо этого вы должны вернуть ключ, который вы разместили, - это строка.

+0

Хороший ответ и описание. Мои предложения: (1), что GetKeysFromValue должен возвращать новый список () вместо null и (2) GetFirstKeyFromValue должен просто вызвать GetKeysFromValue. –

+0

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

+0

@RickDavin Я написал их оба в том случае, если на самом деле OP не нуждается в нескольких ключах. Также я подумал, что было бы более полезно показать оба способа, а не вызвать другую функцию, чтобы показать, как это будет сделано. Что касается возврата пустого списка вместо нуля: во втором взгляде я согласен. Я обновлю это. – JNYRanger

Смежные вопросы