tags:

views:

2906

answers:

5

I have 2 dictionaries of type <string,object> in C# How can I copy all the contents of one Dictionary object to the other without applying a loop?

A: 
Dictionary<string, string> copy = new Dictionary<string, string>(sourceDictionary);
Dmitry Ornatsky
That only makes a copy of the dictionary - it doesn't add two dictionaries together, which I believe is what Pradeep wants?
snemarch
it's not clear from the OP's post to be fair
annakata
Not real clear, but the precondition "I have 2 dictionaries" kinda implies the intention to combine them.
AaronLS
+4  A: 
var result = dictionaries.SelectMany(dict => dict)
             .ToDictionary(pair => pair.Key, pair => pair.Value);
Koistya Navin
+5  A: 

You can use Concat:

        Dictionary<string, object> d1 = new Dictionary<string, object>();
        d1.Add("a", new object());
        d1.Add("b", new object());
        Dictionary<string, object> d2 = new Dictionary<string, object>();
        d2.Add("c", new object());
        d2.Add("d", new object());

        Dictionary<string, object> d3 = d1.Concat(d2).ToDictionary(e => e.Key, e => e.Value);

        foreach (var item in d3)
        {
            Console.WriteLine(item.Key);
        }
bruno conde
This will return an IEnumerable<DictionaryEntry<string,object>>, you will need to call ToDictionary to get a dictionary.
Richard Szalay
That's true. Thanks for pointing that out. Will edit.
bruno conde
A: 

First up, it's not possible without looping. Whether that loop is done in a (extension) method is irrelevent, it still requires a loop.

I'm actually going to recommend doing it manually. All the other answers given require using two extention methods (Concat - ToDictionary and SelectMany - ToDictionary) and thus looping twice. If you are doing this to optimise your code, it will be faster to do a loop over dictionary B and add it's contents to dictionary A.

Edit: After further investigation, the Concat operation would only occur during the ToDictionary call, but I still think a custom extension method would be more efficient.

If you want to reduce your code size, then just make an extension method:

public static class DictionaryExtensions
{
    public static IDictionary<TKey,TVal> Merge<TKey,TVal>(this IDictionary<TKey,TVal> dictA, IDictionary<TKey,TVal> dictB)
    {
        IDictionary<TKey,TVal> output = new Dictionary<TKey,TVal>(dictA);

        foreach (KeyValuePair<TKey,TVal> pair in dictB)
        {
            // TODO: Check for collisions?
            output.Add(pair.Key, Pair.Value);
        }

        return output;
    }
}

Then you can use it by importing ('using') the DictionaryExtensions namespace and writing:

IDictionary<string,objet> output = dictA.Merge(dictB);

I have made the method act like the objects are immutable, but you could easily modify it to not return a new dictionary and just merge into dictA.

Richard Szalay
+4  A: 
d1.Concat(d2).ToDictionary(x => x.Key, x => x.Value);
Gordon Mackie JoanMiro
This is exactly the same as bruno's answer.
Richard Szalay
Simplefied but the same answer yes, not a reason to downvote
PoweRoy
Sorry but I posted before bruno updated his answer to include the ToDictionary call - previously the code was returning an IEnumerable<Dictionary>
Gordon Mackie JoanMiro
Oh great! So I get voted down because bruno went back and updated his answer AFTER mine!
Gordon Mackie JoanMiro
Check the dates, you added your post 3 minutes after his edit.
Richard Szalay
FYI, I can't remove the downvote because it's too old.
Richard Szalay
I seem to recall that his edit to add the ToDictionary call happened an hour after my post - but what the heck - I've calmed down now and it ain't the end of the world :-)
Gordon Mackie JoanMiro
I upvoted you man. I've been burned by being a few seconds too late in the past, so I feel your pain. (I also upvoted Bruno as well.) :-)
Pretzel