2012-05-21 11 views
8

Ich habe eine Frage zu Linq/Lambda und das folgende Problem:C# Wörterbücher schneiden

Ich habe zwei Wörterbücher, primäre und sekundäre ... Diese beiden Wörterbücher sind definiert als Key = String Value = int. Ich muss das primäre Wörterbuch verkleinern, wenn sich die KEYS mit dem sekundären Wörterbuch überschneiden.

dh:

primaryDict = ["thing1", 33] ["thing2", 24] ["thing3", 21] ["thing4", 17] ["thing5", 12] 

secondaryDict = ["thing1", 22] ["thing3", 20] ["thing4", 19] ["thing7", 17] ["thing9", 10] 

resultDict = ["thing1", 33] ["thing3", 21] ["thing4", 17] 

Mein Versuch:

resultDict = primaryDict.Keys.Intersect(secondaryDict.Keys).ToDictionary(t => t.Key, t.Value); 

Das ist offensichtlich nicht funktioniert, weil die primaryDict.Keys.Intersect eine Liste der Schlüssel der Rückkehr ... wie würde ich wieder herstellen einen neuen Wörterbuch oder paarweise das primäre Wörterbuch? Jede Hilfe wäre willkommen.

Antwort

17

Sie könnten auf diese Weise:

resultDict = primaryDict.Keys.Intersect(secondaryDict.Keys) 
           .ToDictionary(t => t, t => primaryDict[t]); 

oder alternativ:

resultDict = primaryDict.Where(x => secondaryDict.ContainsKey(x.Key)) 
         .ToDictionary(x => x.Key, x => x.Value); 

letzteres vielleicht ist etwas effizienter, weil die Schaffung einer Wegwerf-Sammlung vermeidet (die durch die Intersect-Methode erzeugt eine) und keinen zweiten Zugang-für-Schlüssel benötigt zu primaryDict.

EDIT (per Kommentar):

resultDict = 
primaryDict.Where(x => secondaryDict.ContainsKey(x.Key)) 
      .ToDictionary(x => x.Key, x => x.Value + secondaryDict[x.Key]); 
+1

Ich denke, die letzte Version ist viel besser, als ich nicht glaube, das Wörterbuch als IEnumerable Behandlung wird das Wörterbuch nutzen, und wird in O laufen (n) Zeit. –

+0

Das hat gut funktioniert für das was ich mache ... Ich habe die zweite Lösung benutzt und alles funktioniert wie erwartet. Du schaukelst Dave! –

+0

Als Follow Up ... ist es möglich, die Werte in diesem Ausdruck zu summieren? –

2

Ungeprüfte:

resultDict = primaryDict.Keys.Intersect(secondaryDict.Keys).ToDictionary(t => t.Key, primaryDict[t.Key]); 
3

Sie noch primaryDict in Ihrer Linq-Anweisung verwenden können, da Sie eine neue Wörterbuch erstellen, die auf Ihre Variable wird nur dann vergeben, wenn es erstellt wird:

resultDict = primaryDict.Keys 
         .Intersect(secondaryDict.Keys) 
         .ToDictionary(t => t, primaryDict[t]);