3303 Stimmen

Wie kann man über ein Wörterbuch iterieren?

Ich habe ein paar verschiedene Möglichkeiten, über ein Wörterbuch in C# zu iterieren gesehen. Gibt es eine Standardmethode?

92 Stimmen

@VikasGupta Was würden Sie vorschlagen, um etwas mit einer Sammlung von Schlüssel-Wert-Paaren zu tun, wenn Sie nicht wissen, wie die Schlüssel lauten werden?

11 Stimmen

@nasch: myDictionary.Keys erhalten Sie eine Sammlung, die die Schlüssel in myDictionary .

33 Stimmen

@displayName Wenn Sie etwas mit jedem Schlüssel-Wert-Paar machen wollen, aber keinen Verweis auf die Schlüssel haben, um die Werte nachzuschlagen, würden Sie über das Wörterbuch iterieren, richtig? Ich wollte nur darauf hinweisen, dass es Fälle geben kann, in denen man das tun möchte, obwohl Vikas behauptet, dass dies in der Regel eine falsche Verwendung ist.

88voto

Jaider Punkte 13198

C# 7.0 eingeführt Dekonstrukteure und wenn Sie die .NET Core 2.0+ Anwendung, die Struktur KeyValuePair<> enthalten bereits eine Deconstruct() für Sie. Das können Sie tun:

var dic = new Dictionary<int, string>() { { 1, "One" }, { 2, "Two" }, { 3, "Three" } };
foreach (var (key, value) in dic) {
    Console.WriteLine($"Item [{key}] = {value}");
}
//Or
foreach (var (_, value) in dic) {
    Console.WriteLine($"Item [NO_ID] = {value}");
}
//Or
foreach ((int key, string value) in dic) {
    Console.WriteLine($"Item [{key}] = {value}");
}

enter image description here

74voto

George Mauer Punkte 109944

Ich würde sagen foreach ist der Standardweg, obwohl es natürlich davon abhängt, wonach Sie suchen

foreach(var kvp in my_dictionary) {
  ...
}

Ist es das, wonach Sie suchen?

51voto

Onur Punkte 802

Sie können dies auch bei großen Wörterbüchern für die Multithreading-Verarbeitung ausprobieren.

dictionary
.AsParallel()
.ForAll(pair => 
{ 
    // Process pair.Key and pair.Value here
});

35voto

Liath Punkte 9382

Ich schätze, dass diese Frage bereits viele Antworten erhalten hat, aber ich wollte ein wenig Forschung einbringen.

Die Iteration über ein Wörterbuch kann im Vergleich zur Iteration über ein Array recht langsam sein. In meinen Tests dauerte eine Iteration über ein Array 0,015003 Sekunden, während eine Iteration über ein Wörterbuch (mit der gleichen Anzahl von Elementen) 0,0365073 Sekunden dauerte - das ist 2,4 Mal so lang! Ich habe allerdings noch viel größere Unterschiede gesehen. Zum Vergleich: Eine Liste lag mit 0,00215043 Sekunden irgendwo dazwischen.

Aber das ist wie der Vergleich von Äpfeln und Birnen. Mein Punkt ist, dass die Iteration über Wörterbücher langsam ist.

Wörterbücher sind für Suchvorgänge optimiert, daher habe ich zwei Methoden entwickelt. Eine macht einfach ein foreach, die andere durchläuft die Schlüssel und schaut dann nach.

public static string Normal(Dictionary<string, string> dictionary)
{
    string value;
    int count = 0;
    foreach (var kvp in dictionary)
    {
        value = kvp.Value;
        count++;
    }

    return "Normal";
}

Dieser lädt die Schlüssel und iteriert stattdessen über sie (ich habe auch versucht, die Schlüssel in einen string[] zu ziehen, aber der Unterschied war vernachlässigbar.

public static string Keys(Dictionary<string, string> dictionary)
{
    string value;
    int count = 0;
    foreach (var key in dictionary.Keys)
    {
        value = dictionary[key];
        count++;
    }

    return "Keys";
}

Bei diesem Beispiel benötigte der normale foreach-Test 0,0310062 und die Schlüsselversion 0,2205441. Das Laden aller Schlüssel und die Iteration über alle Suchvorgänge ist eindeutig um einiges langsamer!

Für einen abschließenden Test habe ich meine Iteration zehnmal durchgeführt, um zu sehen, ob es irgendwelche Vorteile gibt, die Schlüssel hier zu verwenden (zu diesem Zeitpunkt war ich einfach nur neugierig):

Hier ist die RunTest-Methode, falls Ihnen das hilft, die Vorgänge zu veranschaulichen.

private static string RunTest<T>(T dictionary, Func<T, string> function)
{            
    DateTime start = DateTime.Now;
    string name = null;
    for (int i = 0; i < 10; i++)
    {
        name = function(dictionary);
    }
    DateTime end = DateTime.Now;
    var duration = end.Subtract(start);
    return string.Format("{0} took {1} seconds", name, duration.TotalSeconds);
}

Hier dauerte der normale foreach-Lauf 0,2820564 Sekunden (etwa zehnmal länger als eine einzelne Iteration - wie zu erwarten). Die Iteration über die Schlüssel dauerte 2,2249449 Sekunden.

Bearbeitet um hinzuzufügen: Als ich einige der anderen Antworten las, fragte ich mich, was passieren würde, wenn ich Dictionary anstelle von Dictionary verwenden würde. In diesem Beispiel benötigte das Array 0,0120024 Sekunden, die Liste 0,0185037 Sekunden und das Dictionary 0,0465093 Sekunden. Man kann also davon ausgehen, dass der Datentyp einen Einfluss darauf hat, wie viel langsamer das Wörterbuch ist.

Was sind meine Schlussfolgerungen? ?

  • Vermeiden Sie die Iteration über ein Wörterbuch, wenn Sie können, sind sie wesentlich langsamer als die Iteration über ein Array mit den gleichen Daten in ihm.
  • Wenn Sie sich für die Iteration über ein Wörterbuch entscheiden, sollten Sie nicht versuchen, zu clever zu sein, auch wenn Sie viel langsamer sind als mit der Standard foreach-Methode.

34voto

rucamzu Punkte 823

Wie bereits zu diesem Thema ausgeführt réponse , KeyValuePair<TKey, TValue> implementiert eine Deconstruct Methode ab .NET Core 2.0, .NET Standard 2.1 und .NET Framework 5.0 (Vorschau).

Damit ist es möglich, durch ein Wörterbuch in einer KeyValuePair agnostische Weise:

var dictionary = new Dictionary<int, string>();

// ...

foreach (var (key, value) in dictionary)
{
    // ...
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X