I'm developing an app in C# targeting .NET 3.5. In it, I have 2 similar dictionaries that contain validation criteria for a specific set of elements in my app. Both dictionaries have identical signatures. The first dictionary has the default settings and the 2nd dictionary contains some user defined settings.
var default_settings = new Dictionary<string, MyElementSettings>();
var custom_settings = new Dictionary<string, MyElementSettings>();
I would like to combine the 2 dictionaries into one that contains the elements of both dictionaries.
The problem that I am running into is it is possible for both dictionaries to have the some of the same key values. The basic rule I want is to have a combination of both dictionary and if there are any keys in the custom_settings that already exist in the default_settings, the custom_settings value will overwrite the default_settings value. The best solution i have is just a foreach loop, check if the key exists in the other dictionary, and if not, add it.
foreach (var item in custom_settings)
{
if (default_settings.ContainsKey(item.Key))
default_settings[item.Key] = item.Value;
else
default_settings.Add(item.Key, item.Value);
}
I've done some basic LINQ queries, but I'm still working on learning the more advanced stuff. I've seen a few queries that will merge 2 dictionaries, but most involve grouping any element with duplicate keys, or only return a collection with just the duplicate keys/ Is there a LINQ query or expression that will mimic the behavior of the foreach loop I am using?
Here's a nice extension method based on Ani's answer.
Two points:
So your
foreach
loop is essentially equivalent to:Now that's pretty terse already, so I don't think LINQ is going to help you all that much.
If your going to do this a lot, then I'd recommend writing an equality comparer for dictionary keys:
And then whenever you need to merge dictionaries, you can do the following
I think the answer I selected originally is still the best answer for this particular case, I found myself in another similar situation a little while ago where I had 2
IEnumerable<>
objects that I wanted to convert to a dictionary and merge together in a similar fashion so I thought I would add that solution here to help someone in the future. Rather than converting both to a dictionary and using the method in the selected answer, I found a new approach.I actually posted the initial solution on SE-CodeReview and actually had a suggestion to refine it further. Here's the final code I used:
The key to this is
Foo
must overrideEquals()
to define whatFoo
objects can be considered duplicate, and the members that define which objects are duplicate should also be theDictionary<>
key (in this caseName
)If you can't override
Equals()
inFoo
, then the other option is to useConcat()
andGroupBy()
instead ofUnion()