Как получить словарь TValue из TKey в C #? - PullRequest
3 голосов
/ 06 января 2010

Я объявил словарь obj.

Dictionary<string, string> aDict = new Dictionary<string, string>(); 
        aDict .Add("IP", "Host"); 

Как я вспомнил,

Выражение aDict[IP] может возвращать значение (Host).

Теперь, если я пойду в обратном направлении.

Как получить ключ от стоимости? aDict[Host]?

Является ли Словарь улицей с односторонним движением в C # и работает только от ключа к значению? спасибо.

Ответы [ 4 ]

19 голосов
/ 06 января 2010

Словари не работают так, как и не предназначены. Как бы вы решили следующее:

key = "1", value = "x",
key = "2", value = "x"

Вы можете сделать это:

var keys = dict.Where(kvp => kvp.Value == someValue).Select(kvp => kvp.Key);
foreach(var key in keys) {
    Console.WriteLine(key);
}

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

class TwoWayDictionary<TLeft, TRight> {
    IDictionary<TLeft, TRight> leftToRight = new Dictionary<TLeft, TRight>();
    IDictionary<TRight, TLeft> rightToLeft = new Dictionary<TRight, TLeft>();

    public void Add(TLeft left, TRight right) {
        if (leftToRight.ContainsKey(left)) {
            throw new InvalidOperationException("key left is duplicate");
        }
        if (rightToLeft.ContainsKey(right)) {
            throw new InvalidOperationException("key right is duplicate");
        }
        leftToRight.Add(left, right);
        rightToLeft.Add(right, left);
    }

    public bool TryGetRightByLeft(TLeft left, out TRight right) {
        return leftToRight.TryGetValue(left, out right);
    }

    public bool TryGetLeftByRight(out TLeft left, TRight right) {
        return rightToLeft.TryGetValue(right, out left);
    }
}

Обратите внимание, что это предполагает, что ни один ключ никогда не дублируется.

Теперь вы можете сказать:

TwoWayDictionary<string, string> dict = new TwoWayDictionary<string, string>();
dict.Add("127.0.0.1", "localhost");

string host;
dict.TryGetRightByLeft("127.0.0.1", out host);
// host is "localhost"

string ip;
dict.TryGetLeftByRight("localhost", out ip);
// ip is "127.0.0.1"
3 голосов
/ 06 января 2010

Словарь - это односторонний поиск. Вы все еще можете перебирать все записи в Словаре, ища значение «Хост», если вам нужно. Если вы планируете делать это много, вы можете просто использовать два словаря и синхронизировать их.

1 голос
/ 06 января 2010

Да, словарь - это улица с односторонним движением. Например, многие ключи могут иметь значение «Host», поэтому простого обратного просмотра не существует.

Однако вы можете перебирать словарь, отмечая, какие ключи соответствуют требуемому значению:

foreach (var entry in dict)
{
  if (entry.Value == desiredValue)
    found.Add(entry.Key);
}

Очевидно, что это не эффективно для больших словарей.

1 голос
/ 06 января 2010

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

 foreach(string s in Dict.Keys)
 {
   if(Dict[s] == TheValue)
       ;//we found it!
 }
...