2012-05-21 18 views
8

Mam pytanie o Linq/Lambda i następujący problem:C# słowniki przecinają

mam dwa słowniki, pierwotne i wtórne ... Te dwa słowniki są zdefiniowane jako klucz = ciąg, wartość = int. Muszę przyciąć podstawowy słownik, jeśli KLAWISZE przecinają się ze słownikiem dodatkowym.

tj:

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] 

Moja próba:

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

To oczywiście nie działa, ponieważ primaryDict.Keys.Intersect zwraca listę kluczy ... jak bym ponownie nawiązać nowe słownik lub sparować główny słownik? Każda pomoc będzie doceniona.

Odpowiedz

17

Możesz zrobić w ten sposób:

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

lub alternatywnie

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

ten ostatni może nieco bardziej wydajne, ponieważ unika się tworzenia zbioru jednorazowe (ten wytwarzać metodą Przecięcie) i nie wymaga drugiego wejścia-by-klucza do primaryDict.

EDIT (jak w komentarzu):

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

myślę, że ostatnia wersja jest znacznie lepsza, ponieważ nie sądzę, traktując słownika jako IEnumerable wykorzysta słownika, i będzie działał w czasie O (n) czas. –

+0

To zadziałało doskonale dla tego, co robię ... Użyłem drugiego rozwiązania i wszystko działa zgodnie z oczekiwaniami. Kołysałeś Dave'a! –

+0

Jako kontynuację ... czy można zsumować wartości w tym samym wyrażeniu? –

2

Nietestowane:

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

Można nadal używać primaryDict w swoim oświadczeniu Linq od tworzysz nową słownika , który tylko zostanie przypisana do zmiennej po jej utworzeniu:

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