2017-05-04 76 views
2

我试图做一个程序,它读取有一句话及其含义的字符串,例如向c#中的散列表中的单个键添加多个值?

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

回答

3

在一般情况下,你可以使用List<string>为价值,只是Add它。然而,你也许可以使用LINQ通过ToLookup简化:

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

现在您可以访问groups[key],让你与前缀的所有值,也可以在foreachgroups得到的.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); 

(无需首先检查它是否存在,它只是正常工作;如果没有匹配)

但是!你只需要这样做,如果你仍然想所有之后,即你在其他地方使用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) 

这是可测量的更有效如果这是一个炎热的路径。

+0

谢谢,你能否将它应用于我的代码,以便我可以看到它是如何工作的,因为我对此仍然很陌生。 – Cor

+0

@确定;但是:如果有2行以'Book'作为前缀,你想在列表框中使用什么值?他们全部?或第一个?或最后? –

+0

♦在我们的例子'book'中它们都有两个含义,我想将它们都添加到列表框中。谢谢! – Cor

0

使用Dictionary<string, List<string>>代替散列表。

2

使用字典其中的值是一个字符串列表:

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

而现在,你会做到以下几点:

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

myDicitonary[key].Add(value); 
0

使用Dictionary代替。

Dictionary<string, list<string>> dic = new Dictionary<string, list<string>(); 
相关问题