【问题标题】:Adding more than one value to a single key in a hashtable in c#?在 c# 中向哈希表中的单个键添加多个值?
【发布时间】:2017-05-04 08:10:29
【问题描述】:

我正在尝试制作一个程序,它可以读取具有单词及其含义的字符串,例如

Book: Cover with Papers in between
Book: Reserve

每当我尝试我的代码时,我都会收到一个错误,因为每个键都必须是唯一的。有没有办法解决这个问题?

Hashtable ht = new Hashtable();
        var fileStream = new FileStream(@"e:\test.txt", FileMode.Open, FileAccess.Read);
        using (var streamReader = new StreamReader(fileStream, Encoding.UTF8))
        {

            string line;
            while ((line = streamReader.ReadLine()) != null)
            {
                ht.Add(line.Split(':')[0], line.Split(':')[1]);
            }
        }

        if (ht.ContainsKey("Book"))
        {
            listBox1.Items.Add(ht["Book"].ToString());
        }

【问题讨论】:

    标签: c# hashtable


    【解决方案1】:

    在一般情况下,您可以使用List<string> 作为值,而只使用Add。但是,您可以通过ToLookup 使用 LINQ 进行简化:

    var groups = File.ReadLines(path)
                .Select(line => line.Split(':'))
                .ToLookup(x => x[0], x => x[1].Trim());
    

    现在您可以访问groups[key],它会为您提供带有该前缀的所有值,或者您可以通过groups 获取foreach 以获取.Key 和值的每个组合。

    就您的代码而言,这是:

    var groups = File.ReadLines(@"e:\test.txt")
                .Select(line => line.Split(':'))
                .ToLookup(x => x[0], x => x[1].Trim());
    
    foreach(var val in groups["Book"])
        listBox1.Items.Add(val);
    

    (不需要先检查是否存在,如果不匹配就可以正常工作)

    但是!如果您仍然想要 allafter 此代码,您只需要这样做,即您在其他地方使用 groups。如果您不这样做,您可以更加节俭并放弃不需要的数据:

    var values = File.ReadLines(@"e:\test.txt")
                 .Where(line => line.StartsWith("Book:"))
                 .Select(line => line.Substring(5).Trim());
    
    foreach(var val in values)
        listBox1.Items.Add(val);
    

    编辑:小事 - 一个令人烦恼的方法签名意味着 line.Split(':') 实际上每次都会创建一个数组,因为 params;所以我通常使用:

    static readonly char[] Colon = {':'};
    

    line.Split(Colon)
    

    如果是热路径,如果这是一条更有效的路径。

    【讨论】:

    • 谢谢,您能否将它应用到我的代码中,以便我看看它是如何工作的,因为我对此还是很陌生。
    • @Cor 确定;但是:如果有 2 行以 Book 为前缀,您想在列表框中使用什么值?他们都是?还是第一个?还是最后一个?
    • ♦ 所有这些,在我们的示例中,'book' 有两个含义,我想将两者都添加到列表框中。谢谢!
    • @Cor 我添加了两个这样做的例子,具体取决于您的具体需求
    【解决方案2】:

    使用字典,其中值是字符串列表:

    var myDicitonary = new Dictionary<string, List<string>>
    

    现在,您将执行以下操作:

    if (!myDictionary.ContainsKey(key))
    {
        myDicitonary.Add(key, new List<string>());
    }
    
    myDicitonary[key].Add(value);
    

    【讨论】:

      【解决方案3】:

      使用Dictionary&lt;string, List&lt;string&gt;&gt; 代替哈希表。

      【讨论】:

        【解决方案4】:

        根据您想要实现的目标,您可以使用 SortedListSortedDictionary,使用您自己的 IComparer 进行初始化,这允许重复键。
        查看这些 Stackoverflow 帖子了解详细信息:

        C# Sortable collection which allows duplicate keys
        Is there an alternative to Dictionary/SortedList that allows duplicates?

        此解决方案的缺点是,您无法通过键访问元素,但仍可以通过索引访问。

        【讨论】:

          【解决方案5】:

          改用字典。

          Dictionary<string, list<string>> dic = new Dictionary<string, list<string>();
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-06-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-02-01
            相关资源
            最近更新 更多