2013-10-22 97 views
8

我想反轉鍵和字典的值。 I.e源詞典Dictionary<int, string>,我想獲得Dictionary<string, List<int>>。有List<int>,因爲值可以在不同的密鑰下多次在源字典中。反轉鍵和字典中的值

例子:

{ 
    1: "A" 
    2: "A" 
    3: "A" 
    4: "B" 
    5: "B" 
    6: "C" 
    7: "D" 
} 

將轉變爲:

{ 
    "A": [1,2,3] 
    "B": [4,5] 
    "C": [6] 
    "D": [7] 
} 

感謝您的幫助。

編輯:

OK,從你們的幫助,我能夠了解一點這個算法。 現在我看到了兩種可能的解決方案(除其他之外),並且不知道它們之間的真正區別是什麼,因爲結果似乎是相同的。

是否有任何性能問題?

var byLookup = actions.ToLookup(pair => pair.Value, pair => pair.Key) 
    .ToDictionary(group => group.Key, group => group.AsEnumerable()); 
var byGroupBy = actions.GroupBy(pair => pair.Value, pair => pair.Key) 
    .ToDictionary(group => group.Key, group => group.AsEnumerable()); 

編輯2:

最後我用剛剛

var byLookup = actions.ToLookup(pair => pair.Value, pair => pair.Key) 

我沒想到會是這麼簡單。 謝謝大家。

+1

你想創建一個從字典查找?如果是這種情況,ToLookup()擴展方法就是你的朋友。 – Baldrick

+1

@B ...我試圖找出它,但無法通過所有參數和重載讓我的頭在GroupBy方法上。 – sidon

+0

只需'var byLookup = actions.ToLookup(pair => pair.Value,pair => pair.Key)'就足夠了,您並不需要對ToDictionary進行調用。 –

回答

23

這是一個相當簡單的LINQ表達式:

var res = dict 
    .GroupBy(p => p.Value) 
    .ToDictionary(g => g.Key, g => g.Select(pp => pp.Key).ToList()); 

首先,按價值。這創建了以字符串作爲鍵的組,並將KeyValuePair<int,string>作爲其項目。

然後,通過使用字典鍵的組鍵,將組轉換爲字典,並將原始字典的鍵「扁平化」爲列表ToList()

+0

感謝您的幫助。我更新了我的問題,請問你能看看嗎? – sidon

+0

@sidon你展示的兩種方法幾乎是一樣的,因爲最後你會得到一本字典。儘管如此,除非您確實知道不會多次列舉字典中的列表,否則不應該將'AsEnumerable()'留在那裏。 – dasblinkenlight

+0

@sidon如果有查找對象而不是字典對象是可以接受的,那麼可以完全跳過「ToDictionary」。 – dasblinkenlight

3

你也可以得到你要的結果如下:

var result = source 
    .GroupBy(x => x.Value, x => x.Key) 
    .ToDictionary(g => g.Key, g => g.ToList()); 

這給了相同的結果dasblinkenlight,但條款移動KeyValuePair的映射成團