2013-12-18 68 views
3

我有兩個類型的字典(字符串,字符串)。我需要比較這些並創建一個只有Keys不匹配的新字典。例如,假定這些值按鍵比較兩個字典,並創建一個新的密鑰不匹配

Dictionary A 

Key Value 
========= 
A  B 
C  D 


Dictionary B 

Key Value 
========= 
A  Z 
E  D 

我需要建立一個新的字典,只會有一個單一入口(E,d)

==== ====編輯

當比較完成時,我只是涉及到鍵,這些值是沒有意義的。關鍵值只是字符串,因此不要鏈接到其他對象。沒有隱藏的映射等。「價值」只有當我得到的字典,因爲這是在我的程序中使用時發揮作用。想想這個問題,就好像這些值不存在一樣,我只是試圖獲取字典「B」中但不是「字典」A中的鍵列表。我對鍵「C」沒有興趣,因爲我我的唯一值只是在字典裏「B」只是興趣,但沒有在字典裏「A」

+4

在這種情況下(C,D)會發生什麼?換句話說,您是否只希望字典B中的鍵與字典A中的條目不匹配? –

+0

我們可以假定一個值不是從同一個字典中的不同鍵映射而來的嗎?也就是說,我們在同一個字典中不能有例如'(A => B)'和'(C => B)'? –

+0

這個問題不足以給出正確的答案。 – Jocke

回答

8

要創建包含的B所有元素,它的鍵是不是A字典:

var C = B.Where(x => !A.ContainsKey(x.Key)) 
     .ToDictionary(x => x.Key, x => x.Value); 

如果您想要創建一個包含B的所有元素的字典,其值爲A,但其鍵值與A的值不匹配,可以使用:

var C = 
    (from a in A 
    join b in B on a.Value equals b.Value 
    where a.Key != b.Key 
    select b) 
    .ToDictionary(x => x.Key, x => x.Value); 

不過請注意,如果A包含兩個或更多個鍵,例如相同的值,這將失敗(A, B)(C, D)(F, D)。爲了解決這個你可以做這樣的事情:

var C = 
    (from a in A 
    group a by a.Value into g 
    let a = g.First() 
    join b in B on a.Value equals b.Value 
    where a.Key != b.Key 
    select b) 
    .ToDictionary(x => x.Key, x => x.Value); 
+1

這看起來不正確:我認爲OP想要(E,D),因爲'D'在不同的密鑰下的字典A中。 – dasblinkenlight

+0

@dasblinkenlight我不確定。 'D'是值之一,但OP指出「*創建一個新的字典,只有鍵不匹配*」。 –

+0

這正是讓我認爲他想要的鑰匙不匹配的部分,但這些值確實匹配(請參閱Dan J的評論)。 – dasblinkenlight

8

所以你只需要添加中存在的第二詞典這不是在第一,而不是相反分錄?

var dictC = dictB.Keys.Except(dictA.Keys) 
    .ToDictionary(bKey => bKey, bKey => dictB[bKey]); 

如果你也想的相反,你可以使用在一個匿名類型使用Concat這種方法:

var dictC = dictB.Keys.Except(dictA.Keys) 
    .Select(bKey => new{ Key=bKey, Value=dictB[bKey] }) 
    .Concat(dictA.Keys.Except(dictB.Keys) 
    .Select(aKey => new{ Key=aKey, Value=dictA[aKey] })) 
    .ToDictionary(kv => kv.Key, kv => kv.Value); 

重複鍵是不可能的,因爲在這裏第一個查詢會在字典的1鍵這不在另一箇中,而第二個查詢尋找相反的結果。所以使用ConcatToDictionary是安全的。

+1

這看起來也是一種很好的方法。我很好奇哪種解決方案會更快。 –

+1

這看起來不正確:我認爲OP想要(E,D),因爲'D'在不同的密鑰下的字典A中。 – dasblinkenlight

+0

@dasblinkenlight:嗯,也許。但是,如果重複值有一個匹配鍵而另一個沒有匹配鍵,會發生什麼情況?問題不明確。 –

0

看起來你想要字典B中的鍵值對,其中字典A對於該值具有不同的鍵。在這種情況下,我會做這樣的事情:

// sample data 
Dictionary<string, string> a = new Dictionary<string, string>(); 
a.Add("A", "B"); a.Add("C", "D"); 
Dictionary<string, string> b = new Dictionary<string, string>(); 
b.Add("A", "Z"); b.Add("E", "D"); 

// first, reverse dictionary A for simplicity 
// to quickly get the key for a value 
var revA = a.ToDictionary(kv => kv.Value, kv => kv.Key); 

// and then compute the result 
var result = b.Where(kv => revA.ContainsKey(kv.Value) && revA[kv.Value] != kv.Key) 
       .ToDictionary(kv => kv.Key, kv => kv.Value); 

當然,這是假設,我們不能在同一個字典,從不同的鍵映射到一個值。也就是說,我們不能在同一字典中使用例如(A=>B)(C=>B)。我認爲這在你的問題中是隱含的。

相關問題