232


39

NET基本クラスライブラリに、重複キーの使用を許可する辞書クラスがありますか。 私が見つけた唯一の解決策は、例えば以下のようなクラスを作成することです。
辞書>

しかし、これは実際に使用するのは非常に苛立ちです。 Javaでは、MultiMapがこれを達成すると信じていますが、.NETでは類推できません。

22 Answer


209


NET 3.5を使用している場合は、http://msdn.microsoft.com/en-us/library/bb460184.aspx [Lookup]クラスを使用してください。

編集:あなたは通常http://msdn.microsoft.com/en-us/library/system.linq.enumerable.tolookup.aspx [Enumerable.ToLookup]を使って` Lookup`を作成します。 これは、後で変更する必要がないことを前提としています - しかし、私は通常それで十分だと思います。

それが_うまくいかない場合、フレームワークに何か役立つものはないと思います - そして辞書を使うことはそれが得るのと同じくらい良いです:(


148


Listクラスは実際には、コレクションを反復処理したい場合に重複を含むキー/値コレクションに対して非常にうまく機能します。 例:

リスト>リスト=新しいリスト>();

// add some values to the collection here

for(int i = 0; i <list.Count; i){Print(list [i] .Key、list [i] .Value); }


37


これをList <KeyValuePair <string、string>>で行う1つの方法があります。

パブリッククラスListWithDuplicates:List> {public void Add(string key、string value){var element = new KeyValuePair(key、value); this.Add(element); }}

var list = new ListWithDuplicates(); list.Add( "k1"、 "v1"); list.Add( "k1"、 "v2"); list.Add( "k1"、 "v3");

foreach(リスト内のvar項目){文字列x =文字列.format( "{0} = {1}、"、item.Key、item.Value); }

出力k1 = v1、k1 = v2、k1 = v3


21


キーと値の両方に文字列を使用している場合は、 System.Collections.Specialized.NameValueCollectionを使用できます。これは、GetValues(string key)メソッドを介して文字列値の配列を返します。


17


私はちょうど PowerCollectionsライブラリに出会いました。これには、とりわけ、MultiDictionaryというクラスが含まれています。 これはきちんとこのタイプの機能性を包みます。


14


Lookupの使用に関する非常に重要な注意事項

IEnumerable(T)`を実装するオブジェクトに対して `ToLookup`を呼び出すことで Lookup(TKey、TElement) `のインスタンスを作成することができます

`Lookup(TKey、TElement)`の新しいインスタンスを作成するためのパブリックコンストラクタはありません。 さらに、 `Lookup(TKey、TElement)`オブジェクトは不変です。つまり、作成後に `Lookup(TKey、TElement)`オブジェクトに要素やキーを追加したり削除したりすることはできません。

私はこれがほとんどの用途にとってショーストッパーになると思います。


10


私は `List>`のようなものが仕事をすると思う。


8


NET = 4以上を使用している場合は、Tupleクラスを使用できます。
// declaration
var list = new List>>();

// to add an item to the list
var item = Tuple>("key", new List);
list.Add(item);

// to iterate
foreach(var i in list)
{
    Console.WriteLine(i.Item1.ToString());
}


6


http://www.itu.dk/research/c5/[C5's] http://www.itu.dk/research/c5/Release1.0/c5doc/types/C5.HashBag%601.htmをご覧ください。 #T:C5.HashBag%601%7CM:C5.HashBag%601.Add(%600)[HashBag]クラス。


4


「重複キー」エントリを許可する辞書を「自分で」作成するのは簡単です。 これは大まかな簡単な実装です。 あなたは基本的に(全部ではないにしても)ほとんどの `IDictionary`のサポートを追加することを検討したいかもしれません。

public class MultiMap
{
    private readonly Dictionary> storage;

    public MultiMap()
    {
        storage = new Dictionary>();
    }

    public void Add(TKey key, TValue value)
    {
        if (!storage.ContainsKey(key)) storage.Add(key, new List());
        storage[key].Add(value);
    }

    public IEnumerable Keys
    {
        get { return storage.Keys; }
    }

    public bool ContainsKey(TKey key)
    {
        return storage.ContainsKey(key);
    }

    public IList this[TKey key]
    {
        get
        {
            if (!storage.ContainsKey(key))
                throw new KeyNotFoundException(
                    string.Format(
                        "The given key {0} was not found in the collection.", key));
            return storage[key];
        }
    }
}

使い方の簡単な例:

const string key = "supported_encodings";
var map = new MultiMap();
map.Add(key, Encoding.ASCII);
map.Add(key, Encoding.UTF8);
map.Add(key, Encoding.Unicode);

foreach (var existingKey in map.Keys)
{
    var values = map[existingKey];
    Console.WriteLine(string.Join(",", values));
}