【问题标题】:Adding many rows to C# dictionary at once一次向 C# 字典添加多行
【发布时间】:2017-11-24 19:51:44
【问题描述】:

如果我实例化一个新的Dictionary,我可以传入许多值:

Dictionary<string, string> data = new Dictionary<string, string>(){
    { "Key1", "Value1" },
    { "Key2", "Value2" },
    { "Key3", "Value3" },
    { "Key4", "Value4" },
    { "Key5", "Value5" },
}

但是,如果我已经有一个Dictionary,例如当它传入参数时,我需要为每个键值对调用Add

data.Add("Key1", "Value1");
data.Add("Key2", "Value2");
data.Add("Key3", "Value3");
data.Add("Key4", "Value4");
data.Add("Key5", "Value5");

我想知道是否有一种“速记”方法可以一次将大量值添加到现有字典中 - 最好是原生的?如果是这样,我们欢迎权威的“不”。


没有我想要的那么干净,但这是我知道的两种选择。

这个允许一次传递多个值,但需要创建一个新的Dictionary 而不是更新现有的:

Dictionary<string, string> newData = new Dictionary<string, string>(data)
{
    { "Key6", "Value6"},
    { "Key7", "Value7"},
    { "Key8", "Value8"},
};

也可以创建一个扩展方法,但这仍然为每一行调用Add

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);
    }
}

【问题讨论】:

  • 您在第一个示例中显示的语法实际上已被编译器修改为多次调用 Add,因此效果相同
  • @MatthewSteeples 作为初学者 C# 开发人员很高兴了解

标签: c# dictionary


【解决方案1】:

如果是这样,我们欢迎权威的“不”。

就是这样。

不,没有AddRange 或等效项,因为没有实用的方法可以一次将多个项目添加到字典中。 List 一次添加多个项目是有意义的,因为它们可以通过一个命令复制到内部数组中。

对于Dictionary,必须计算每个项目的哈希码以确定值将存储在哪个“桶”中,因此必然需要对每个项目进行迭代。因此,AddRange 方法或其等效方法充其量只是语法糖。在最坏的情况下,需要定义如果列表中的任何项目已经存在会发生什么。它会抛出异常吗?如果是这样,在重复之前添加的项目会保留在字典中吗?如果不是,它会默默地跳过该项目还是替换重复项?

这些问题没有直观的正确答案,因此没有预先定义。

【讨论】:

    【解决方案2】:

    如果您经常需要向字典中添加多个项目,您可以制作扩展方法

    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));
      }
    }
    

    以上内容适用于批量添加已知独特的项目。如果您需要担心欺骗,那么您需要添加健全性检查,并可能返回一个布尔列表,让您知道哪个成功了.. 但此时您最好放弃扩展方法,因为很多便利会迷路了。

    【讨论】:

      【解决方案3】:

      你可以做一个扩展来完成这个任务。

       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;
                  }
              }
      

      这是一个通用函数,可以接受另一个字典。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-06-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-07
        • 2021-11-18
        • 2018-07-27
        • 1970-01-01
        相关资源
        最近更新 更多