Вопрос

What is the best way to add multiple values to a Dictionary if I don't want to call ".Add()" multiple times.

Edit: I want to fill it after initiation! there are already some values in the Dictionary!

So instead of

    myDictionary.Add("a", "b");
    myDictionary.Add("f", "v");
    myDictionary.Add("s", "d");
    myDictionary.Add("r", "m");
    ...

I want to do something like this

 myDictionary.Add(["a","b"], ["f","v"],["s","d"]);

Is there a way to do so?

Это было полезно?

Решение

You can use curly braces for that, though this only works for initialization:

var myDictionary = new Dictionary<string, string>
{
    {"a", "b"},
    {"f", "v"},
    {"s", "d"},
    {"r", "m"}
};

This is called "collection initialization" and works for any ICollection<T> (see link for dictionaries or this link for any other collection type). In fact, it works for any object type that implements IEnumerable and contains an Add method:

class Foo : IEnumerable
{
    public void Add<T1, T2, T3>(T1 t1, T2 t2, T3 t3) { }
    // ...
}

Foo foo = new Foo
{
    {1, 2, 3},
    {2, 3, 4}
};

Basically this is just syntactic sugar for calling the Add-method repeatedly. After initialization there are a few ways to do this, one of them being calling the Add-methods manually:

var myDictionary = new Dictionary<string, string>
    {
        {"a", "b"},
        {"f", "v"}
    };

var anotherDictionary = new Dictionary<string, string>
    {
        {"s", "d"},
        {"r", "m"}
    };

// Merge anotherDictionary into myDictionary, which may throw
// (as usually) on duplicate keys
foreach (var keyValuePair in anotherDictionary)
{
    myDictionary.Add(keyValuePair.Key, keyValuePair.Value);
}

Or as extension method:

static class DictionaryExtensions
{
    public static void Add<TKey, TValue>(this IDictionary<TKey, TValue> target, IDictionary<TKey, TValue> source)
    {
        if (source == null) throw new ArgumentNullException("source");
        if (target == null) throw new ArgumentNullException("target");

        foreach (var keyValuePair in source)
        {
            target.Add(keyValuePair.Key, keyValuePair.Value);
        }
    }
}

var myDictionary = new Dictionary<string, string>
    {
        {"a", "b"},
        {"f", "v"}
    };

myDictionary.Add(new Dictionary<string, string>
    {
        {"s", "d"},
        {"r", "m"}
    });

Другие советы

This isn't exactly a duplicate question, but what you probably want is for there to be a Dictionary.AddRange() method. And here is why that doesn't exist:

Why doesn't Dictionary have AddRange?

"Range doesn't really have any meaning to an associative container."

But it might be a good idea to write your own .AddRange() method to the Dictionary class. It would essentially be a loop of .Add() calls though.

Although the question has been answered, I was curious if it would be possible to apply collection initializer-like syntax to a dictionary that was already initialized without the creation/overhead of creating a second dictionary to merge and throw away.

You can use (abuse?) Collection Initializers to add a range of values to an existing Dictionary after it's creation. How? By creating a helper class to do it:

public class AddRangeTo<TKey, TValue> : IEnumerable
{
    private readonly IDictionary<TKey, TValue> WrappedDictionary;

    public AddRangeTo(IDictionary<TKey, TValue> wrappedDictionary)
    {
        this.WrappedDictionary = wrappedDictionary;
    }

    public void Add(TKey key, TValue value)
    {
        this.WrappedDictionary.Add(key, value);
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        throw new NotSupportedException();
    }
}

With usage:

var myDictionary = new Dictionary<string, string>();

new AddRangeTo<string, string>(myDictionary)
{
    {"a", "b"},
    {"f", "v"},
    {"s", "d"},
    {"r", "m"}
};

Notice this allows you to add entries to the dictionary using a similar syntax but to a dictionary that's already been initialized. The part that kind of sucks is the repeat of the <string, string> generics, but that will not be necessary come C# 6.0. (EDIT: That is, in C# 6 it would look like new AddRangeTo(myDictionary)) (EDIT: This feature was scrapped from C# 6)

That all being said, I don't really recommend doing this necessarily. This is odd syntax/usage with unexpected side effects and I think might be confusing to others when they come across it. But if you find you would actually use this a lot and make your internal code easier to use and maintain, then bonus!

You can do it at initialization like all other answer show, or you can combine it with this trick:

Dictionary<string, string> myDictionary = new Dictionary<string, string>();
Dictionary<string, string> secondDictionary = new Dictionary<string, string>()
{ 
    {"1", "a"}, 
    {"2", "b"} 
};
myDictionary = myDictionary.Union(secondDictionary)
                           .ToDictionary(kvp => kvp.Key, kvp => kvp.Value);

You have to make sure there are no duplicate keys or you will get an exception (but this ist the same with the Add method).

You can do it like this:

var myDict = new Dictionary<string, string>() 
{
    {"a", "aa"},
    {"b", "bb"},
    {"c", "cc"},
    {"d", "dd"}
};

This can be done out of the main code path in a way that allows you to reduce the clutter where it is happening using extension methods.

public static class DictionaryExtensions
{
  public static IDictionary<TKey,TValue> AddRange<TKey,TValue>(
               this IDictionary<TKey,TValue> source,
               params  KeyValuePair<TKey,TValue>[] items)
  {
    foreach (var keyValuePair in items)
    {
      source.Add(keyValuePair.Key, keyValuePair.Value);
    }
    return source;
  }
}

That would have been an easy google search: http://msdn.microsoft.com/en-us/library/bb531208.aspx. Anyways...here is the code:

Dictionary<string, string> myDictionary = new Dictionary<string, string>()
{
    { 'a', 'b' },
    { 'c', 'd' },
    { 'e', 'f' }
};

Of course, you can also write a loop or something to iterate over your values and calling the .add() method each time.

Well, you can on initialization:

new Dictionary<string, string> { {"a","b"}, {"f","v"},{"s","d"} }

This is called a collection initializer. When you want to add multiple items to an already existing dictionary, you can write a method.

I have the perfect example for this initialization. Let's say you want to convert roman to integer. You receive a string with the roman number and you need a way to map what each character means. In c# you would use a dictionary with the characters and their equivalent integer

var map = new Dictionary<char, int>{
        {'M',1000},
        {'D',500},
        {'C',100},
        {'L',50},
        {'X',10},
        {'V',5},
        {'I',1}
    };

myDictionary = new Dictionary() { {"a", 2) }, { "b", 3 }, };

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top