278

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

Dictionary<string, List<object>>

しかし、これは実際に使用するのはかなりイライラします。Java では、MultiMap がこれを達成すると信じていますが、.NET では類似物を見つけることができません。

4

24 に答える 24

236

.NET 3.5 を使用している場合は、Lookupクラスを使用します。

編集: 通常、Lookupusing を作成しEnumerable.ToLookupます。これは、後で変更する必要がないことを前提としていますが、通常はそれで十分です。

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

于 2008-09-28T16:46:37.970 に答える
185

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

List<KeyValuePair<string, string>> list = new List<KeyValuePair<string, string>>();

// add some values to the collection here

for (int i = 0;  i < list.Count;  i++)
{
    Print(list[i].Key, list[i].Value);
}
于 2009-05-08T21:02:55.110 に答える
43

List< KeyValuePair< string, string > > を使用してこれを行う 1 つの方法を次に示します。

public class ListWithDuplicates : List<KeyValuePair<string, string>>
{
    public void Add(string key, string value)
    {
        var element = new KeyValuePair<string, string>(key, value);
        this.Add(element);
    }
}

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

foreach(var item in list)
{
    string x = string.format("{0}={1}, ", item.Key, item.Value);
}

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

于 2012-03-23T18:14:14.540 に答える
25

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

于 2008-09-28T16:39:02.747 に答える
19

とりわけ、MultiDictionary というクラスを含むPowerCollectionsライブラリに出くわしました。これにより、このタイプの機能がきちんとラップされます。

于 2008-09-28T16:39:45.350 に答える
14

ルックアップの使用に関する非常に重要な注意事項:

を実装するオブジェクトをLookup(TKey, TElement)呼び出すことで、 のインスタンスを作成できます。ToLookupIEnumerable(T)

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

(MSDN より)

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

于 2008-09-28T20:24:24.327 に答える
14

私は何かList<KeyValuePair<object, object>>が仕事をするだろうと思います。

于 2008-09-28T16:37:47.240 に答える
11

>= .NET 4 を使用している場合は、Tupleクラスを使用できます。

// declaration
var list = new List<Tuple<string, List<object>>>();

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

// to iterate
foreach(var i in list)
{
    Console.WriteLine(i.Item1.ToString());
}
于 2012-08-17T05:52:21.900 に答える
4

元の質問への回答。TheDictionary<string, List<object>>と呼ばれるクラスに実装されているようなものです。MultiMapCode Project

以下のリンクで詳細を確認できます: http://www.codeproject.com/KB/cs/MultiKeyDictionary.aspx

于 2010-05-28T13:00:43.623 に答える
3

このList<KeyValuePair<string, object>>オプションを使用すると、LINQ を使用して検索を実行できます。

List<KeyValuePair<string, object>> myList = new List<KeyValuePair<string, object>>();
//fill it here
var q = from a in myList Where a.Key.Equals("somevalue") Select a.Value
if(q.Count() > 0){ //you've got your value }
于 2011-07-19T15:37:23.183 に答える
3

NameValueCollection は、1 つのキー (文字列でもあります) の下で複数の文字列値をサポートしますが、これは私が認識している唯一の例です。

そのような機能が必要な状況に遭遇したとき、私はあなたの例に似た構造を作成する傾向があります。

于 2008-09-28T16:41:35.813 に答える
2

私の使い方はただ

Dictionary<string, List<string>>

このようにして、文字列のリストを保持する単一のキーがあります。

例:

List<string> value = new List<string>();
if (dictionary.Contains(key)) {
     value = dictionary[key];
}
value.Add(newValue);
于 2012-04-07T17:59:52.160 に答える
2

実際の重複ではなく、合同ということですか?そうしないと、ハッシュテーブルは機能しません。

合同とは、2 つの別個のキーが同等の値にハッシュできることを意味しますが、キーは等しくありません。

例: ハッシュテーブルのハッシュ関数が単に hashval = key mod 3 だったとします。1 と 4 の両方が 1 にマップされますが、値は異なります。ここで、リストのアイデアが役立ちます。

1 を検索する必要がある場合、その値は 1 にハッシュされ、Key = 1 が見つかるまでリストが走査されます。

重複するキーの挿入を許可すると、どのキーがどの値にマップされるかを区別できなくなります。

于 2008-09-28T16:38:58.953 に答える
1

同じ答えを探してこの投稿に出くわしましたが、何も見つからなかったので、辞書のリストを使用して必要最小限のソリューション例を作成し、 [] 演算子をオーバーライドして、他のすべての辞書が新しい辞書を持っているときにリストに新しい辞書を追加しました。指定されたキー (set) を取得し、値のリストを返します (get)。
それは醜くて非効率的で、キーでのみ取得/設定し、常にリストを返しますが、機能します:

 class DKD {
        List<Dictionary<string, string>> dictionaries;
        public DKD(){
            dictionaries = new List<Dictionary<string, string>>();}
        public object this[string key]{
             get{
                string temp;
                List<string> valueList = new List<string>();
                for (int i = 0; i < dictionaries.Count; i++){
                    dictionaries[i].TryGetValue(key, out temp);
                    if (temp == key){
                        valueList.Add(temp);}}
                return valueList;}
            set{
                for (int i = 0; i < dictionaries.Count; i++){
                    if (dictionaries[i].ContainsKey(key)){
                        continue;}
                    else{
                        dictionaries[i].Add(key,(string) value);
                        return;}}
                dictionaries.Add(new Dictionary<string, string>());
                dictionaries.Last()[key] =(string)value;
            }
        }
    }
于 2011-05-23T16:11:43.410 に答える
-1

U は、辞書を使用したい場所ごとに複合文字列キーを作成する方法を定義できます。たとえば、この方法を使用してキーを作成する必要があります。

private string keyBuilder(int key1, int key2)
{
    return string.Format("{0}/{1}", key1, key2);
}

使用するため:

myDict.ContainsKey(keyBuilder(key1, key2))
于 2015-05-25T12:50:11.767 に答える
-3

重複キーは、ディクショナリの契約全体を破ります。ディクショナリでは、各キーは一意であり、単一の値にマップされます。オブジェクトを任意の数の追加オブジェクトにリンクしたい場合、最善の策は DataSet (一般的にはテーブル) に似たものかもしれません。キーを 1 つの列に入れ、値をもう 1 つの列に入れます。これはディクショナリよりも大幅に遅くなりますが、それはキー オブジェクトをハッシュする機能を失うこととのトレードオフです。

于 2008-09-28T16:38:09.253 に答える
-4

これも可能です:

Dictionary<string, string[]> previousAnswers = null;

このようにして、一意のキーを持つことができます。これがうまくいくことを願っています。

于 2015-04-19T21:19:39.577 に答える