29

There doesn't seem to be a dictionary.AddRange() method. Does anyone know a better way to copy the items to another dictionary without using a foreach loop.

I'm using the System.Collections.Generic.Dictionary. This is for .NET 2.0.

Helephant
  • 16,258
  • 8
  • 38
  • 35

7 Answers7

24

There's the Dictionary constructor that takes another Dictionary.

You'll have to cast it IDictionary, but there is an Add() overload that takes KeyValuePair<TKey, TValue>. You're still using foreach, though.

bluish
  • 24,718
  • 26
  • 114
  • 174
ageektrapped
  • 14,332
  • 7
  • 55
  • 70
19

There's nothing wrong with a for/foreach loop. That's all a hypothetical AddRange method would do anyway.

The only extra concern I'd have is with memory allocation behaviour, because adding a large number of entries could cause multiple reallocations and re-hashes. There's no way to increase the capacity of an existing Dictionary by a given amount. You might be better off allocating a new Dictionary with sufficient capacity for both current ones, but you'd still need a loop to load at least one of them.

Mike Dimmick
  • 9,572
  • 2
  • 22
  • 46
14
var Animal = new Dictionary<string, string>();

one can pass existing animal Dictionary to the constructor.

Dictionary<string, string> NewAnimals = new Dictionary<string, string>(Animal);
Chizl
  • 1,838
  • 15
  • 31
Mahendra Thorat
  • 141
  • 1
  • 2
3

For fun, I created this extension method to dictionary. This should do a deep copy wherever possible.

public static Dictionary<TKey, TValue> DeepCopy<TKey,TValue>(this Dictionary<TKey, TValue> dictionary)
        {
            Dictionary<TKey, TValue> d2 = new Dictionary<TKey, TValue>();

            bool keyIsCloneable = default(TKey) is ICloneable;
            bool valueIsCloneable = default(TValue) is ICloneable;

            foreach (KeyValuePair<TKey, TValue> kvp in dictionary)
            {
                TKey key = default(TKey);
                TValue value = default(TValue);
                if (keyIsCloneable)
                {
                    key = (TKey)((ICloneable)(kvp.Key)).Clone();
                }

                else
                {
                    key = kvp.Key;
                }

                if (valueIsCloneable)
                {
                    value = (TValue)((ICloneable)(kvp.Value)).Clone();
                }

                else
                {
                    value = kvp.Value;
                }

                d2.Add(key, value);
            }

            return d2;
        }
BFree
  • 100,265
  • 20
  • 154
  • 199
0

For a primitive type dictionary:

public void runIntDictionary()
{
    Dictionary<int, int> myIntegerDict = new Dictionary<int, int>() { { 0, 0 }, { 1, 1 }, { 2, 2 } };
    Dictionary<int, int> cloneIntegerDict = new Dictionary<int, int>();
    cloneIntegerDict = myIntegerDict.Select(x => x.Key).ToList().ToDictionary<int, int>(x => x, y => myIntegerDict[y]);
}

or with an Object that implement ICloneable:

public void runObjectDictionary()
{
    Dictionary<int, number> myDict = new Dictionary<int, number>() { { 3, new number(3) }, { 4, new number(4) }, { 5, new number(5) } };
    Dictionary<int, number> cloneDict = new Dictionary<int, number>();
    cloneDict = myDict.Select(x => x.Key).ToList().ToDictionary<int, number>(x => x, y => myDict[y].Clone());
}

public class number : ICloneable
{
    public number()
    {
    }
    public number(int newNumber)
    {
        nr = newnumber;
    }
    public int nr;

    public object Clone()
    {
        return new number() { nr = nr };
    }
    public override string ToString()
    {
        return nr.ToString();
    }
}
Marcello
  • 440
  • 5
  • 17
0

If you're dealing with two existing objects, you might get some mileage with the CopyTo method: http://msdn.microsoft.com/en-us/library/cc645053.aspx

Use the Add method of the other collection (receiver) to absorb them.

Oli
  • 228,145
  • 62
  • 212
  • 294
0

I don't understand, why not using the Dictionary( Dictionary ) (as suggested by ageektrapped ).

Do you want to perform a Shallow Copy or a Deep Copy? (that is, both Dictionaries pointing to the same references or new copies of every object inside the new dictionary?)

If you want to create a new Dictionary pointing to new objects, I think that the only way is through a foreach.

jfs
  • 16,677
  • 12
  • 60
  • 88
Martin Marconcini
  • 25,191
  • 19
  • 103
  • 139
  • Shallow copy is fine. I have two dictionaries that I'm populating in a method and I want to copy the second smaller dictionary into the first one at the end of the method. I need to keep them separate during the life of the method because they mean different things. – Helephant Sep 17 '08 at 10:05