2012-05-21 41 views
8

Tôi có một câu hỏi về LINQ/Lambda và vấn đề sau đây:C# từ điển giao nhau

Tôi có hai bộ từ điển, tiểu học và trung ... Hai từ điển được định nghĩa là chính = chuỗi, giá trị gia tăng = int. Tôi cần phải cắt giảm từ điển chính nếu KEYS giao cắt với từ điển phụ.

ví dụ:

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] 

nỗ lực của tôi:

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

Điều này rõ ràng không hoạt động vì primaryDict.Keys.Intersect được trả lại một danh sách các phím ... sẽ như thế nào tôi thiết lập lại một mới từ điển hoặc ghép nối từ điển chính? Bất kỳ trợ giúp sẽ được đánh giá cao.

Trả lời

17

Bạn có thể thực hiện theo cách này:

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

hoặc, cách khác:

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

sau này có lẽ là hơi hiệu quả vì tránh việc tạo ra một bộ sưu tập ném-đi (một trong những tạo ra theo phương pháp Intersect) và không đòi hỏi một truy cập-by-key thứ hai hơn đến primaryDict.

EDIT (theo bình luận):

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

Tôi nghĩ rằng phiên bản cuối cùng là tốt hơn nhiều, như tôi không nghĩ rằng điều trị điển như một IEnumerable sẽ tận dụng từ điển, và sẽ chạy trong thời gian O (n) thời gian. –

+0

Điều đó làm việc rất tốt cho những gì tôi đang làm ... Tôi đã sử dụng giải pháp thứ hai và mọi thứ đang hoạt động như mong đợi. Bạn đá Dave! –

+0

Theo dõi ... liệu có thể tổng hợp các giá trị trong cùng một biểu thức này không? –

2

chưa được kiểm tra:

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

Bạn vẫn có thể sử dụng primaryDict trong tuyên bố LINQ của bạn vì bạn đang tạo một mới từ điển, mà chỉ được gán cho biến của bạn khi nó được tạo ra:

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