webentwicklung-frage-antwort-db.com.de

C # erhält Schlüssel und Werte aus der Liste <KeyValuePair <String, String>

Gegeben eine Liste: 

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

(HINWEIS: Für den Schlüssel "qwer" gibt es mehrere Werte und für den Wert "asdf" mehrere Schlüssel.)

1) Gibt es eine bessere Methode, um eine Liste aller Schlüssel zurückzugeben, als nur ein foreach auf der KeyValuePair-Liste zu machen?

2) Gibt es einen besseren Weg, um eine Liste aller Werte für einen bestimmten Schlüssel zurückzugeben, als mit foreach?

3) Und wie wäre es dann, wenn Sie eine Liste von Schlüsseln für einen bestimmten Wert zurückgeben?

Vielen Dank...

12
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" }
18
Jashaszun

Es klingt, als würden Sie davon profitieren, wenn Sie Folgendes verwenden:

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
}

Es ist relativ einfach, eine grundlegende Mehrfachwörterbuch-Klasse mithilfe eines Wörterbuchs und einer Liste zu erstellen.

Dieser Blogbeitrag spricht mehr über den über NuGet verfügbaren MultiDictionary-Typ von Microsoft.

5
Robert Horvick

Sie können NameValueCollection aus dem System.Collection.Specialized-Namespace verwenden:

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");

Anwendungsbeispiel:

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/de-de/library/system.collections.specialized.namevaluecollection%28v=vs.110%29.aspx

2
Fabjan

Nun, Sie könnten definitiv Ihre LINQ verwenden. Es ist jedoch nicht "besser" (in Bezug auf die Leistung), da das Looping bereits schnell ist. Es ist vielleicht lesbarer (persönliche Präferenz). Beachten Sie bei allen Antworten, dass der System.Linq-Namespace importiert werden muss. Sie geben auch IEnumerable<T> zurück, die faul geladen sind (ausgeführt, wenn sie wiederholt werden). Wenn Sie eine konkrete Liste zurückgeben möchten, können Sie die Erweiterung .ToList() aufrufen.

Gibt es eine bessere Methode, um eine Liste aller Schlüssel zurückzugeben, als nur ein foreach auf der KeyValuePair-Liste durchzuführen?

KV_List.Select(kvp => kvp.Key);

Gibt es in ähnlicher Weise einen besseren Weg, um eine Liste aller Werte für einen bestimmten Schlüssel zurückzugeben, als mit foreach?

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

Und wie wäre es dann, wenn Sie eine Liste von Schlüsseln für einen bestimmten Wert zurückgeben?

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

Weitere Informationen zu LINQ finden Sie unter LINQ (Sprachintegrierte Abfrage)

2
Simon Belanger

Ich würde in Ihrem Fall ILookup<K,V> verwenden. Es ist wie ein Wörterbuch, aber Sie können die Werte als IEnumerable<V> mit demselben Schlüssel erhalten.

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

oder einfach

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

Lesen Sie dies und wundern sich, warum jemand Code erstellt hat, der ein IEnumerable <KeyValuePair <A, B> anstelle eines Dictionary <A, B> hat, aber keine Lust haben zu fragen und einfach fertig werden möchten?

if (collection == null)
    return null;

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