2013-07-08 112 views
-1

我创建了一个System.Collections.Generic.Dictionaryd并使用int - string填充了键值对。词典:从值中获取密钥

鉴于密钥k,我可以通过调用d[k]来获得它的值。

但是,我该如何做到相反?也就是说,给定值v,我如何获得密钥?

+3

由于字典的值不是唯一的,因此无法可靠地做到这一点。尽管它的键必须是唯一的,但它的值不会,因此您必须遍历其键和值并返回与该值匹配的键数组。 – Pharap

+0

这是一个频繁重复的问题;看到http://stackoverflow.com/questions/2444033/get-dictionary-key-by-value – jltrem

+0

作为Pharap说,你的代码需要,如果有多个重复的值来处理索引数组。如果您只关心找到的第一个索引,请使用.FirstOrDefault()。 – MadHenchbot

回答

5

一种选择是通过所有的对迭代找一个(或多个)与你正在寻找的价值,然后从这些对获得钥匙。如果您愿意搜索整个词典并且没有快速的查询速度,这将是适当的。

如果这是你正在做的很多事情,那么它表明你的字典是“倒退”的,它应该被颠倒,或者你应该做字典,一个用于“向前”查找和一个用于“向后”查找。这样做会使程序的内存占用量增加一倍,并且复杂度也会明显增加(您需要确保两个集合保持同步)。你可以找到一些“双向字典”(即this one by Jon Skeet)的现有解决方案,它将把这两个字典封装在一个类中(这样你就不需要做工作来确保它们保持同步;操作会变异两本字典)。如果这是你做了很多事情,请考虑使用或制作这种类型。

+2

+1 - 请参阅[Jon Skeet的回答](http://stackoverflow.com/a/255638/187697)了解双向版本。 – keyboardP

2

您将有特定的值超过一个关键,所以只要使用LINQ,你可以得到的结果:

var keys = dic.Where(p => p.Value == v) 
       .Select(p => p.Key); 

为了提高访问的性能,您可以创建一个逆词典:

var inverseDic = dic.GroupBy(p => p.Value) 
        .ToDictionary(g => g.Key, 
            g => g.Select(p => p.Key)); 

因此,要拿到钥匙:

var keys = inverseDic[v]; 
0

这应该够做这样的事情:

var dic = new Dictionary<int, string>() {....} 
var foundKey = dic.FirstOrDefault(kvp=>kvp.Value == YOUR_SEARCH_VALUE_HERE).Key; 
0
var key = dictionary.FirstOrDefault(d => d.Value == value).Key; 
0

你可以这样做:

var dict = new Dictionary<TKey, TValue>() ... 
TValue myValue = ... 
var myKey = dict.First(pair => pair.Value == myValue).Key; 

如果该值未在字典中找到这可能会失败。要成为一个更加安全,你可以这样做:

var myKey = dict.FirstOrDefault(pair => pair.Value == myValue).Key; 

这里myKey将采取(字符串或其他类,0为整数,等nullTKey类型的默认值,所以根据您的具体情况您可能需要小心处理这种情况。

此外,重要的是要认识到你可以有许多具有相同值的键。要选择按键的所有使用:

var myKeys = dict.Where(pair => pair.Value == myValue).Select(pair => pair.Key); 

或者在查询语法:

var myKeys = 
    from pair in dict 
    where pair.Value == myValue 
    select pair.Key; 
0
var key = dictionary.FirstOrDefault(d => d.Value == value).Key; 
+0

这不会编译。你有一对序列,你不能从序列中获得密钥。你需要采取第一,或从他们所有的选择(如果你想他们全部)的关键。 – Servy

+0

是的,是的。我的意思是第一。编辑。 –

0

是的,你可以使用d [K],但不要忘了用d.ContainsKey(k)或你例外。你可以use var key = d.FirstOrDefault(x => x.Value == value).Key;

0

如果这是你会经常做,或者如果你想确保每个值只加一次,你应该做一个自定义数据类型里面坐了两点字典:一个<int,string>和其他<string,int>。你可以像任何一种类型的普通字典一样使用它。类的声明可能是这样的:

public class DoubleDictionary<T1, T2> : IDictionary<T1, T2>, IDictionary<T2, T1> 

乔恩斯基特创建了一个全面实施这样一个字典,with每个键without多个值。

+0

请注意,它取决于“值”是否也是唯一的。如果不是,那么它是一个'的IDictionary ,IDictionary的>'因为可能有multilpe'T1'类型集合中的每个'T2'。 – Servy

2
public int[] GetKeys(string value) 
{ 
List<int> list = new List<int>(); 
for(int i = 0;i<dict.Values.Count;i++) 
{ 
if(dict.Values[i] == value){list.Add(dict.Keys[i]);} 
} 
return list.ToArray(); 
}