2017-05-04 6 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になります。しかし、あなたはおそらくToLookup経由でLINQを簡素化することができます:

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

は今、あなたはその接頭辞であなたのすべての値を与える groups[key]にアクセスしたり、 foreach groups.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); 

編集:マイナーなもの - 厄介なメソッドのシグネチャはparamsのでline.Split(':')は、実際に、配列を毎回作成することを意味します。私は通常使用します。

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

、それがホットパスであるあれば測定可能、より効率的である

line.Split(Colon) 

+0

ありがとう、私のコードに適用してもらえますか? – Cor

+0

@確か;しかし:もし 'Book'を接頭辞とする2行があれば、あなたはどの値をリストボックスで使いたいのですか?それらのすべて?または最初の?または最後の? –

+0

♦この例の「book」には2つの意味があります。リストボックスに両方を追加したいと思います。ありがとう! – 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

達成する目標に応じて、SortedListまたはSortedDictionaryを使用して、自分自身でIComparerと初期化すると、重複するキーが許可されます。
は、詳細については、これらのStackOverflowの記事を見てください:

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

この解決策の欠点は、あなたがキーによって、まだインデックスで要素にアクセスすることができないということ、です。

0

代わりに辞書を使用してください。

関連する問題