2013-07-08 53 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(); 
}