1

I have two Dictionary.

Dictionary<string, string> testDict = new Dictionary<string, string>();
            testDict.Add("Name", "John");
            testDict.Add("City", "NY");

Dictionary<string, string> DictA = new Dictionary<string, string>();
            DictA.Add("Name", "Sarah");
            DictA.Add("State", "ON");

I wish to get a Dictionary such that the keys of testDict are present and the values of those keys present in DictA are present.

So the example merged dictionary should look as below:

Dictionary<string, string> DictMerged = new Dictionary<string, string>();
                DictMerged.Add("Name", "Sarah");
                DictMerged.Add("City", "NY");

I hope I have been able to explain my requirements..

I tried..

testDict.Concat(DictA)
  .GroupBy(kvp => kvp.Key, kvp => kvp.Value)
  .ToDictionary(g => g.Key, g => g.Last());

But this gave me DictA 'State' as well which I do not want..

Any help is sincerely appreciated

Thanks

Hossein Narimani Rad
  • 31,361
  • 18
  • 86
  • 116
Arnab
  • 2,324
  • 6
  • 36
  • 60

3 Answers3

5

I think you are looking for this:

var result = 
    testDict.ToDictionary(
             i => i.Key, 
             i => DictA.ContainsKey(i.Key) ? DictA[i.Key] : i.Value);

// result:
// {"Name", "Sarah"}
// {"City", "NY"}
Hossein Narimani Rad
  • 31,361
  • 18
  • 86
  • 116
2

If you have the GetOrDefault extension method defined here

Then you can do

var result = testDict.ToDictionary(
    kvp => kvp.Key, 
    kvp => DictA.GetOrDefault(kvp.Key, kvp.Value));

The difference between this and using DictA.ContainsKey(kvp.Key) ? DictA[kvp.Key] : i.Value is that there is only one lookup done on DictA versus two when the key is present.

Community
  • 1
  • 1
juharr
  • 31,741
  • 4
  • 58
  • 93
  • But I think DictA[kvp.key] is O(1) and it is not a O(n) http://stackoverflow.com/a/7532721/1468295 – Hossein Narimani Rad May 20 '15 at 15:10
  • I added the 'GetOrDefault' method in the same class but get two errors : a)Cannot convert lambda expression to type 'System.Collections.Generic.IEqualityComparer' because it is not a delegate type b)'System.Collections.Generic.Dictionary' does not contain a definition for 'GetOrDefault' and no extension method 'GetOrDefault' accepting a first argument of type 'System.Collections.Generic.Dictionary' could be found (are you missing a using directive or an assembly reference?) – Arnab May 20 '15 at 15:11
  • @Arnab I just tested it out and it worked. The second error is because it doesn't see the `GetOrDefault` extension method, likely because of the first error. I'd have to see your code to figure out that first error. That extension method should be inside of a public static class for it to work (though I would expect a different error if that wasn't the case). – juharr May 20 '15 at 15:19
  • @HosseinNarimaniRad Yes, both are O(1) most of the time, but that's 2 constant time lookups instead of one in the case of `TryGetValue`. – juharr May 20 '15 at 15:25
  • @juharr Normally when someone use the **lookup** word, he means O(n). – Hossein Narimani Rad May 20 '15 at 15:36
  • @HosseinNarimaniRad The complexity of a lookup depends on the data structure, so I don't see how it would mean O(n). Now a lot of data structures do have a O(n) for look ups, but that doesn't make them synonymous. – juharr May 20 '15 at 15:40
  • @juharr I agree and that's why I start my sentence with *normally*. – Hossein Narimani Rad May 20 '15 at 15:42
0

This would work

        var testDict = new Dictionary<string, string> { { "Name", "John" }, { "City", "NY" } };
        var DictA = new Dictionary<string, string> { { "Name", "Sarah" }, { "State", "ON" } };
        var mergedDict = testDict.ToDictionary(keyVal => keyVal.Key, keyVal => DictA.ContainsKey(keyVal.Key) ? DictA[keyVal.Key] : keyVal.Value);
austin wernli
  • 1,801
  • 12
  • 15