按值获取字典键

lov*_*iji 336 c# dictionary

如何在C#中按值获取Dictionary键?

Dictionary<string, string> types = new Dictionary<string, string>()
{
            {"1", "one"},
            {"2", "two"},
            {"3", "three"}
};
Run Code Online (Sandbox Code Playgroud)

我想要这样的东西:

getByValueKey(string value);
Run Code Online (Sandbox Code Playgroud)

getByValueKey("one")必须回来"1".

这样做的最佳方式是什么?也许是HashTable,SortedLists?

Kim*_*imi 605

值不一定必须是唯一的,因此您必须进行查找.你可以这样做:

var myKey = types.FirstOrDefault(x => x.Value == "one").Key;
Run Code Online (Sandbox Code Playgroud)

如果值是唯一的并且插入频率低于读取值,则创建一个逆字典,其中值是键,键是值.

  • 警告所有人,如果FirstOrDefault找不到匹配项并尝试访问null对象上的"Key",则接受编辑的接受答案将抛出异常. (13认同)
  • @JimYarbro:因为`KeyValuePair <Tkey,Tvalue>`是一个结构体,所以是一个值类型,它永远不会是"null".`FirstOrDefault`将返回一个实例,其中所有字段都使用其默认值进行初始化(如字符串为"null"或int为0).所以你不会得到例外.但是你也不知道你是否找到了一个值,所以这个答案并不包括该值不存在的情况. (6认同)
  • 我在这里错过了什么吗?上面的代码返回值,而不是键.不会是types.FirstOrDefault(x => x.Value =="one").键更合适吗? (4认同)
  • @loviji:请记住,在循环解决方案中,如果值恰好位于字典的末尾,则必须遍历所有其他值才能找到它.如果您有多个条目,这将减慢您的程序. (3认同)
  • @Zach Johnson:谢谢.我同意你的看法.和你的答案我也喜欢.但在我的字典中有8-10个条目.并且它们不是动态添加的.我认为,使用这个答案不错的解决方案. (2认同)

Zac*_*son 25

你可以这样做:

  1. 通过循环遍历KeyValuePair<TKey, TValue>字典中的所有内容(如果字典中有许多条目,这将是一个相当大的性能影响)
  2. 使用两个词典,一个用于值到键映射,一个用于键到值映射(这将占用内存空间的两倍).

如果不考虑性能,请使用方法1,如果不考虑内存,请使用方法2.

此外,所有键必须是唯一的,但这些值不必是唯一的.您可能有多个具有指定值的键.

你有什么理由不能扭转关键价值关系吗?

  • @KyleDelaney - 是的,但这只是循环遍历所有值的一次。如果没有反向字典,每次需要反向查找时都会发生循环。 (3认同)
  • 为了以编程方式创建逆字典,我们仍然需要使用方法 1,对吧? (2认同)

Jos*_*Gee 7

public static string GetKeyFromValue(string valueVar)
{
    foreach (string keyVar in dictionaryVar.Keys)
    {
        if (dictionaryVar[keyVar] == valueVar)
        {
            return keyVar;
        }
    }
    return null;
}
Run Code Online (Sandbox Code Playgroud)

其他人可能有更有效的答案,但我个人认为这更直观,并且适用于我的情况。


Bor*_*nko 6

我遇到了 Linq 绑定不可用并且不得不显式扩展 lambda 的情况。它产生了一个简单的函数:

public static T KeyByValue<T, W>(this Dictionary<T, W> dict, W val)
{
    T key = default;
    foreach (KeyValuePair<T, W> pair in dict)
    {
        if (EqualityComparer<W>.Default.Equals(pair.Value, val))
        {
            key = pair.Key;
            break;
        }
    }
    return key;
}
Run Code Online (Sandbox Code Playgroud)

像这样调用它:

public static void Main()
{
    Dictionary<string, string> dict = new Dictionary<string, string>()
    {
        {"1", "one"},
        {"2", "two"},
        {"3", "three"}
    };

    string key = KeyByValue(dict, "two");       
    Console.WriteLine("Key: " + key);
}
Run Code Online (Sandbox Code Playgroud)

适用于 .NET 2.0 和其他受限环境。