web-dev-qa-db-ja.com

C#はList <KeyValuePair <string、string>からキーと値を取得します

リストが与えられた場合:

    private List<KeyValuePair<string, string>> KV_List = new List<KeyValuePair<string, string>>();
    void initList()
    {
        KV_List.Add(new KeyValuePair<string, string>("qwer", "asdf"));
        KV_List.Add(new KeyValuePair<string, string>("qwer", "ghjk"));
        KV_List.Add(new KeyValuePair<string, string>("zxcv", "asdf"));
        KV_List.Add(new KeyValuePair<string, string>("hjkl", "uiop"));
    }

(注:キー「qwer」には複数の値があり、値「asdf」には複数のキーがあります。)

1)KeyValuePairリストでforeachを実行するよりも、すべてのキーのリストを返すより良い方法はありますか?

2)同様に、foreachを使用するよりも、特定のキーのすべての値のリストを返すより良い方法はありますか?

3)そして、与えられた値のキーのリストを返すのはどうですか?

ありがとう...

13
frog_jr
// #1: get all keys (remove Distinct() if you don't want it)
List<string> allKeys = (from kvp in KV_List select kvp.Key).Distinct().ToList();
// allKeys = { "qwer", "zxcv", "hjkl" }

// #2: get values for a key
string key = "qwer";
List<string> values = (from kvp in KV_List where kvp.Key == key select kvp.Value).ToList();
// values = { "asdf", "ghjk" }

// #3: get keys for a value
string value = "asdf";
List<string> keys = (from kvp in KV_List where kvp.Value == value select kvp.Key).ToList();
// keys = { "qwer", "zxcv" }
22
Jashaszun

次のようなものを使用することでメリットが得られるようです。

Dictionary<string, List<string>> kvlist;

kvlist["qwer"] = new List<string>();
kvlist["qwer"].Add("value1");
kvlist["qwer"].Add("value2");

foreach(var value in kvlist["qwer"]) {
    // do something
}

辞書とリストを使用して基本的な多値辞書クラスを作成するのは比較的簡単です。

この ブログ投稿 では、NuGetを介して利用可能なMicrosoftのMultiDictionaryタイプについて詳しく説明しています。

5
Robert Horvick

System.Collection.Specialized名前空間のNameValueCollectionを使用できます。

NameValueCollection  KV_List = new NameValueCollection();

KV_List.Add("qwer", "asdf");
KV_List.Add("qwer", "ghjk");
KV_List.Add("zxcv", "asdf");
KV_List.Add("hjkl", "uiop");

使用例:

string singleValue = KV_List["zxcv"];  // returns "asdf"
string[] values = KV_List.GetValues("qwer");  // returns "asdf, "ghjk"
string[] allKeys = KV_List.AllKeys;
string[] allValues = KV_List.AllKeys;

https://msdn.Microsoft.com/en-us/library/system.collections.specialized.namevaluecollection%28v=vs.110%29.aspx

2
Fabjan

LINQを間違いなく使用できます。しかし、ループはすでに高速であるため、(パフォーマンスの点では)「より良い」わけではありません。おそらくもっと読みやすいです(個人的な好み)。以下のすべての回答については、_System.Linq_名前空間をインポートする必要があることに注意してください。また、遅延ロードされた_IEnumerable<T>_を返します(繰り返し処理されたときに実行されます)。具体的なリストを返したい場合は、 .ToList() extension を呼び出すことができます。

KeyValuePair Listでforeachを実行するよりも、すべてのキーのリストを返すより良い方法はありますか?

_KV_List.Select(kvp => kvp.Key);
_

同様に、特定のキーのすべての値のリストを返すには、foreachを使用するよりも良い方法がありますか?

_var theKeyToLookFor = "qwer";
KV_List.Where(kvp => kvp.Key == theKeyToLookFor).Select(kvp => kvp.Value);
_

そして、特定の値のキーのリストを返すのはどうですか?

_var theValueToLookFor = "asdf";
KV_List.Where(kvp => kvp.Value == theValueToLookFor)
       .Select(kvp => kvp.Value)
       .ToList();
_

LINQの詳細については、 LINQ(Language-Integrated Query) をご覧ください。

2
Simon Belanger

私は使うだろう ILookup<K,V>あなたの場合。辞書のようなものですが、値はIEnumerable<V>同じキー。

ILookup<string, string> lookup = KV_List.ToLookup(x => x.Key, x => x.Value);
IEnumerable<string> list = lookup["qwer"];
foreach(string str in list)
{
    Console.WriteLine(str);
}

または単に

Console.WriteLine(string.Join(",", lookup["qwer"]));
1
EZI

1:

KV_List.Select(i => i.Key).ToList()

2:

KV_List.Where(i => i.Key == filterByKey).Select(i => i.Value).ToList()

3:

 KV_List.Where(i => i.Value == filterByValue).Select(i => i.Key).ToList()
0
serhiyb

これを読んで、なぜ誰かがいくつかのコードを作ったのに、Dictionary <A、B>の代わりにIEnumerable <KeyValuePair <A、B >>を持っているのか疑問に思っていますか?

if (collection == null)
    return null;

return collection 
    .Where(z => z.Key == aThing)
    .Select(z => z.Value)
    .FirstOrDefault();
0
Stachu