【问题标题】:Get Dictionary key by using the dictionary value使用字典值获取字典键
【发布时间】:2010-10-23 00:48:30
【问题描述】:

如何通过字典值获取字典键?

当使用键获取值时,如下所示:

Dictionary<int, string> dic = new Dictionary<int, string>();

dic.Add(1, "a");

Console.WriteLine(dic[1]);
Console.ReadLine();

反其道而行之?

【问题讨论】:

标签: c# dictionary


【解决方案1】:

字典实际上是用于从 Key->Value 进行单向查找。

你可以使用 LINQ 做相反的事情:

var keysWithMatchingValues = dic.Where(p => p.Value == "a").Select(p => p.Key);

foreach(var key in keysWithMatchingValues)
    Console.WriteLine(key);

意识到可能有多个具有相同值的键,因此任何适当的搜索都会返回一个键的集合(这就是上面存在 foreach 的原因)。

【讨论】:

  • ack,比我快 35 秒! :)
  • 我猜这可能比 for each 通过 keyvaluepairs 快,但不比反转字典快吧?出于好奇,我必须自己把它放在凳子上,但如果让字典不同的话会更快,对吧?
  • @user999999928 这与通过字典执行 foreach 基本相同。如果您要进行大量查找,构建一个“反向”字典(需要一个集合作为值)会使查找速度更快,但需要同时处理插入/更改。
  • 我得到一个 .Where 字典不存在
【解决方案2】:

蛮力。

        int key = dic.Where(kvp => kvp.Value == "a").Select(kvp => kvp.Key).FirstOrDefault();

【讨论】:

  • int key = dic.FirstOrDefault(kvp => kvp.Value == "a").Key;
  • 但是,如果没有具有该值的键,则会引发异常。 (FirstOrDefault返回null,你取.Key为null)
【解决方案3】:

您也可以使用以下扩展方法从字典中按值获取键

public static class Extensions
{
    public static bool TryGetKey<K, V>(this IDictionary<K, V> instance, V value, out K key)
    {
        foreach (var entry in instance)
        {
            if (!entry.Value.Equals(value))
            {
                continue;
            }
            key = entry.Key;
            return true;
        }
        key = default(K);
        return false;
    }
}

用法也这么简单

int key = 0;
if (myDictionary.TryGetKey("twitter", out key))
{
    // successfully got the key :)
}

【讨论】:

  • +1),因为 zain 正在讲述一种通过扩展方法实现这一点的新方法。
  • 所以如果Values 是一个列表,我会使用indexOf() 而不是Equals()
【解决方案4】:

获取一键的简单方法:

    public static TKey GetKey<TKey,TValue>(Dictionary<TKey, TValue> dictionary, TValue Value)
    {
        List<TKey> KeyList = new List<TKey>(dictionary.Keys);
        foreach (TKey key in KeyList)
            if (dictionary[key].Equals(Value))
                return key;
        throw new KeyNotFoundException();
    }

对于多个键:

    public static TKey[] GetKeys<TKey, TValue>(Dictionary<TKey, TValue> dictionary, TValue Value)
    {
        List<TKey> KeyList = new List<TKey>(dictionary.Keys);
        List<TKey> FoundKeys = new List<TKey>();
        foreach (TKey key in KeyList)
            if (dictionary[key].Equals(Value))
                FoundKeys.Add(key);
        if (FoundKeys.Count > 0)
            return FoundKeys.ToArray();
        throw new KeyNotFoundException();
    }

【讨论】:

    【解决方案5】:

    我意识到这是一个老问题,但想补充一些我想到的东西。

    如果您知道一个值只有一个键,那么您必须通过值和键查找;您可以创建两个单独的字典。一种以原始键为键,值为值,第二种以键为值,值为键。

    现在附注一下;它确实消耗了更多的机器资源,但我猜它比通过 LINQ 和 foreach 暴力破解更快。

    【讨论】:

    • 我也是这么想的。当然,这些值必须是唯一的。我认为这取决于您需要查找多少次值。如果这经常(10 次以上),那可能是值得的。
    猜你喜欢
    • 1970-01-01
    • 2011-01-27
    • 1970-01-01
    • 2014-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多