【问题标题】:c# if key exist in dictionary still add the value in dictionaryc#如果字典中存在键仍然在字典中添加值
【发布时间】:2014-01-06 11:29:02
【问题描述】:

我正在从数据表中获取值并输入Dictionary<string,string>

Dictionary<string, string> mydic= new Dictionary<string, string>();

我的 ex 数据表是

Value     RowOrder    
page1       01 
page2       00
page3       00

我正在使用 LINQ 根据给定的值获取 RowOrder 并放入 mydic

string id = (from DataRow dr in table3.Rows where (string)dr["Value"] == formula
             select (string)dr["RowOrder"]).FirstOrDefault();
mydic.Add(id,Value); 

如果我运行它,则会显示错误:

“已添加具有相同密钥的项目。”

如何克服这一点。我想page1page2page3 应该分别加上值010000

【问题讨论】:

  • 字典不能有重复的键,因此由您决定在这种情况下应该发生什么。
  • 这个问题没有意义。字典的重点是能够通过键查找项目。如果您使用相同的密钥添加多个项目,这怎么可能?如果您查看mydic["00"],您希望看到什么?
  • 如果您有重复的键,那么使用 Dictionary 的意义何在??

标签: c# linq dictionary


【解决方案1】:

在添加之前需要检查字典是否已经有键:

if(!mydic.ContainsKey(id))
{
    mydic.Add(id, Value);
}

字典不能包含具有相同键的两个项目,如果您期望重复的 id 值,则需要考虑使用不同的数据结构。

也许是List&lt;Tuple&lt;string, string&gt;&gt;

【讨论】:

  • @user2380844 没问题,List&lt;KeyValuePair&lt;string, string&gt;&gt; 是个好主意。
【解决方案2】:

添加前检查key是否存在

if (mydic.ContainsKey(id))
    mydic[id] = Value; // or throw exception        
else
    mydic.Add(id, Value);

顺便说一句,如果您想将您的 DataTable 转换为 Dictionary&lt;string, string&gt;,其中 RowOrder 作为键,第一个(或最后一个)Value 作为值,您可以使用 LINQ :

var mydic = table3.AsEnumerable()
                  .GroupBy(r => r.Field<string>("RowOrder"))
                  .Select(g => g.First()) // or last to use last value for key
                  .ToDictionary(r => r.Field<string>("RowOrder"),
                                     r.Field<string>("Value"));

【讨论】:

  • 我知道 GroupBy 会返回一个 IEnumerable>,对吗?如果是这样,我无法了解其余代码在做什么。请你解释一下。
  • @mrida rest 正在从每个组中选择第一行,因此我们避免了重复键的问题。然后将行序列转换为字典
【解决方案3】:

你可以使用GroupBy,这里使用Linq-To-DataSet的单行方法:

Dictionary<string, string> mydic = table3.AsEnumerable()
    .GroupBy(row => row.Field<string>("Value"))
    .ToDictionary(grp => grp.Key, grp => grp.First().Field<string>("RowOrder"));

【讨论】:

    【解决方案4】:

    使用

    mydic[id] = Value;
    

    而不是 mydic.Add(); 如果要确保仅插入具有给定键的一项,则应使用 Add 方法。 请注意,这会覆盖之前写入的值。

    如果您想拥有更多具有相同密钥的项目,您应该使用

    Dictionary<string, IList<string>> 
    

    或其他一些我不知道但我很高兴听到的数据结构,因为我不止一次使用过那种字典

    【讨论】:

      【解决方案5】:

      您可以使用Lookup&lt;string,string&gt;

      List<Tuple<string, string>> tuples = new List<Tuple<string, string>>();
      tuples.Add(new Tuple<string, string>("01", "page1"));
      tuples.Add(new Tuple<string, string>("00", "page2"));
      tuples.Add(new Tuple<string, string>("00", "page3"));
      var lookup = tuples.ToLookup(t => t.Item1,t=> t.Item2 );
      

      你可以像这样使用它:

      var result = lookup["00"];
      foreach (var item in result)
      {
          Console.WriteLine(item);
      }
      

      哪些输出:

      page2
      page3
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-10-29
        • 1970-01-01
        • 2020-06-10
        • 1970-01-01
        • 2015-12-03
        • 2022-08-05
        • 1970-01-01
        • 2020-01-03
        相关资源
        最近更新 更多