Reputation: 8137
If I instantiate a new Dictionary
I can pass in many values:
Dictionary<string, string> data = new Dictionary<string, string>(){
{ "Key1", "Value1" },
{ "Key2", "Value2" },
{ "Key3", "Value3" },
{ "Key4", "Value4" },
{ "Key5", "Value5" },
}
However, if I already have a Dictionary
, such as when it is passed in a parameter, I'm required to call Add
for each key-value pair:
data.Add("Key1", "Value1");
data.Add("Key2", "Value2");
data.Add("Key3", "Value3");
data.Add("Key4", "Value4");
data.Add("Key5", "Value5");
I'm wondering if there's a "shorthand" method for adding in a large number of values to an existing Dictionary at one time - preferably natively? An authoritative "no" is welcome if that be the case.
Not as clean as I'm looking for, but these are the two alternatives I know.
This one allows passing many values at once, but requires creating a new Dictionary
rather than updating the existing one:
Dictionary<string, string> newData = new Dictionary<string, string>(data)
{
{ "Key6", "Value6"},
{ "Key7", "Value7"},
{ "Key8", "Value8"},
};
It's also possible to create an extension method, but this still calls Add
for each row:
public static void AddMany<Tkey, TValue>(this Dictionary<Tkey, TValue> dict, Dictionary<Tkey, TValue> toAdd)
{
foreach(KeyValuePair<Tkey, TValue> row in toAdd)
{
dict.Add(row.Key, row.Value);
}
}
Upvotes: 6
Views: 11274
Reputation: 1678
You can make an extension to achieve this task.
public static class DictionaryHelper
{
public static Dictionary<TKey, TValue> AddRange<TKey, TValue>(this Dictionary<TKey, TValue> destination, Dictionary<TKey, TValue> source)
{
if (destination == null) destination = new Dictionary<TKey, TValue>();
foreach (var e in source)
{
if (!destination.ContainsKey(e.Key))
destination.Add(e.Key, e.Value);
destination[e.Key] = e.Value;
}
return destination;
}
}
This is a generic function that will accept another dictionary.
Upvotes: 0
Reputation: 152566
An authoritative "no" is welcome if that be the case.
That be the case.
No, there is not an AddRange
or equivalent because there is no practical way to add multiple items to a dictionary at one time. It makes sense for a List
to add multiple items at once because they can get copied into the internal array in one command.
For a Dictionary
, the hash code of each item must be computed to determine what "bucket" the value will get stored in, so there is by necessity a need to iterate over each item. Thus an AddRange
method or its equivalent would at best be syntactic sugar. At worst, one would need to define what would happen if any item in the list already existed. Would it throw an exception? If so, would items that were added before the duplicate stay in the dictionary? If not, would it silently skip the item or replace the duplicate?
These are questions that have no intuitively correct answer and thus have not been pre-defined.
Upvotes: 11
Reputation: 5234
If you frequently need to add multiple items to your dictionary you could make an extension method
public static class DictionaryExtensions
{
public static void AddRange<TKey, TValue>(this Dictionary<TKey, TValue> dic, List<KeyValuePair<TKey, TValue>> itemsToAdd)
{
itemsToAdd.ForEach(x => dic.Add(x.Key, x.Value));
}
}
The above would be fine for bulk adding known-unique items. If you need to be concerned about dupes then you'd want to add sanity checks and perhaps return a list of bools to let you know which succeeded .. but at that point you might as well forego the extension method since much of the convenience would be lost.
Upvotes: 0