【问题标题】:Dictionary with list of strings as value以字符串列表为值的字典
【发布时间】:2013-07-26 17:24:57
【问题描述】:

我有一本字典,其中我的值是一个列表。 当我添加键时,如果键存在我想向值(列表)添加另一个字符串? 如果键不存在,那么我创建一个新条目,其中包含一个带有值的新列表,如果键存在,那么我只需向列表值添加一个值 例如。

Dictionary<string, List<string>> myDic = new Dictionary<string, List<string>>();
myDic.Add(newKey, add to existing list<strings> and not create new one)

【问题讨论】:

    标签: c# list dictionary


    【解决方案1】:

    要手动执行此操作,您需要以下内容:

    List<string> existing;
    if (!myDic.TryGetValue(key, out existing)) {
        existing = new List<string>();
        myDic[key] = existing;
    }
    // At this point we know that "existing" refers to the relevant list in the 
    // dictionary, one way or another.
    existing.Add(extraValue);
    

    但是,在许多情况下,LINQ 可以使用ToLookup 使这变得微不足道。例如,考虑一个List&lt;Person&gt;,您希望将其转换为“姓氏”到“该姓氏的名字”的字典。你可以使用:

    var namesBySurname = people.ToLookup(person => person.Surname,
                                         person => person.FirstName);
    

    【讨论】:

    • 如果您在循环中执行此操作,结果将远非预期。我会选择if the key doesn't exist, add it with an empty list as value. Else fill that value with the requested string. 它更有意义,更容易编写。
    • @KappaG3:我不明白你的意思……尤其是在“填充该值”方面——我相信我的回答符合 OP 的要求。
    • 哎呀,我的错。我没有仔细阅读您的代码,并认为它做了一些完全不同的事情。
    • 这里的菜鸟:任何人都知道 namesBySurname 的显式类型声明是什么 - var 关键字对我来说弄得一团糟:'(?
    • @BKSpureon:您始终可以将鼠标悬停在var 上以查看确切的类型。在这种情况下,它将是ILookup&lt;string, string&gt;
    【解决方案2】:

    我会将字典包装在另一个类中:

    public class MyListDictionary
    {
    
        private Dictionary<string, List<string>> internalDictionary = new Dictionary<string,List<string>>();
    
        public void Add(string key, string value)
        {
            if (this.internalDictionary.ContainsKey(key))
            {
                List<string> list = this.internalDictionary[key];
                if (list.Contains(value) == false)
                {
                    list.Add(value);
                }
            }
            else
            {
                List<string> list = new List<string>();
                list.Add(value);
                this.internalDictionary.Add(key, list);
            }
        }
    
    }
    

    【讨论】:

    • 我认为没有任何迹象表明“值列表”仅包含唯一值。
    • 我想不出有什么好的理由将重复的字符串存储在一个列表中,除了性能之外......但这值得商榷。
    • 很多 种情况是合适的。想象一个购物系统中的一个案例,它正在对“订单 ID 的订单项”进行分组——您想区分“这个订单是一个汉堡”和“这个订单是五个汉堡”之间的区别。特别是,据我所知,您已经默默地添加了问题中没有提到的任何方式的行为。
    【解决方案3】:

    只需在字典中创建一个新数组

    Dictionary<string, List<string>> myDic = new Dictionary<string, List<string>>();
    myDic.Add(newKey, new List<string>(existingList));
    

    【讨论】:

      【解决方案4】:

      一个更简单的方法是:

      var dictionary = list.GroupBy(it => it.Key).ToDictionary(dict => dict.Key, dict => dict.Select(item => item.value).ToList());
      

      【讨论】:

        【解决方案5】:

        我为此写了一个字典扩展:

        public static class DictionaryExtensions
        {
            public static void AddOrUpdate(this Dictionary<string, List<string>> targetDictionary, string key, string entry)
            {
                if (!targetDictionary.ContainsKey(key))
                    targetDictionary.Add(key, new List<string>());
        
                targetDictionary[key].Add(entry);
            }
        }
        

        现在您可以简单地添加或更新:

        using System;
        using System.Collections.Generic;
        using DictionaryExtensions;
        
        public class Program
        {
            public static void Main()
            {
                var newDic = new Dictionary<string, List<string>>();
                newDic.AddOrUpdate("Alpha","Anton");
                newDic.AddOrUpdate("Alpha","Boris");
                newDic.AddOrUpdate("Beta","Doris");
                newDic.AddOrUpdate("Delta","Emil");
                newDic.AddOrUpdate("Alpha","Ceasar");
                
                System.Console.Write(newDic["Alpha"][1].ToString());
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2021-01-29
          • 1970-01-01
          • 1970-01-01
          • 2022-11-04
          • 1970-01-01
          • 1970-01-01
          • 2016-10-05
          • 1970-01-01
          • 2021-05-02
          相关资源
          最近更新 更多