Frage

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

War es hilfreich?

Lösung

foreach(KeyValuePair<string, string> entry in myDictionary)
{
    // do something with entry.Value or entry.Key
}

Andere Tipps

Wenn Sie versuchen, ein generisches Wörterbuch in C # verwenden, wie Sie ein assoziatives Array in einer anderen Sprache verwenden würden:

foreach(var item in myDictionary)
{
  foo(item.Key);
  bar(item.Value);
}

Oder, wenn Sie nur über die Sammlung von Schlüsseln iterieren müssen, verwenden Sie

foreach(var item in myDictionary.Keys)
{
  foo(item);
}

Und schließlich, wenn Sie daran interessiert sind nur in den Werten:

foreach(var item in myDictionary.Values)
{
  foo(item);
}

(Beachten Sie, dass das var Schlüsselwort ist eine optionale C # 3.0 und höher Feature, können Sie auch den genauen Typ Ihrer Schlüssel / Werte verwenden hier)

In einigen Fällen können Sie einen Zähler benötigen, die durch for-Schleife Implementierung zur Verfügung gestellt werden kann. Dafür bietet LINQ ElementAt was es ermöglicht, die folgenden:

for (int index = 0; index < dictionary.Count; index++) {
  var item = dictionary.ElementAt(index);
  var itemKey = item.Key;
  var itemValue = item.Value;
}

Abhängig davon, ob Sie nach den Tasten oder die Werte ...

Aus der MSDN Dictionary(TKey, TValue) Klasse Beschreibung:

// When you use foreach to enumerate dictionary elements,
// the elements are retrieved as KeyValuePair objects.
Console.WriteLine();
foreach( KeyValuePair<string, string> kvp in openWith )
{
    Console.WriteLine("Key = {0}, Value = {1}", 
        kvp.Key, kvp.Value);
}

// To get the values alone, use the Values property.
Dictionary<string, string>.ValueCollection valueColl =
    openWith.Values;

// The elements of the ValueCollection are strongly typed
// with the type that was specified for dictionary values.
Console.WriteLine();
foreach( string s in valueColl )
{
    Console.WriteLine("Value = {0}", s);
}

// To get the keys alone, use the Keys property.
Dictionary<string, string>.KeyCollection keyColl =
    openWith.Keys;

// The elements of the KeyCollection are strongly typed
// with the type that was specified for dictionary keys.
Console.WriteLine();
foreach( string s in keyColl )
{
    Console.WriteLine("Key = {0}", s);
}

Im Allgemeinen ohne einen bestimmten Kontext für „die beste Art und Weise“ zu fragen ist wie zu fragen, was ist die beste Farbe

Auf der einen Seite gibt es viele Farben und es gibt keine beste Farbe. Es hängt von der Notwendigkeit und oft auf Geschmack auch.

Auf der anderen Seite gibt es viele Möglichkeiten, über einen Wörterbuch in C # iterieren und es gibt keinen besten Weg. Es hängt von der Notwendigkeit und oft auf Geschmack auch.

direkteste Weg

foreach (var kvp in items)
{
    // key is kvp.Key
    doStuff(kvp.Value)
}

Wenn Sie nur den Wert benötigen (erlaubt es item zu nennen, besser lesbar als kvp.Value).

foreach (var item in items.Values)
{
    doStuff(item)
}

Wenn Sie eine bestimmte Sortierreihenfolge

Im Allgemeinen Anfänger ist überrascht über Reihenfolge der Aufzählung einer Dictionary.

LINQ bietet eine kurze Syntax, um (und viele andere Dinge) angeben können, z.

foreach (var kvp in items.OrderBy(kvp => kvp.Key))
{
    // key is kvp.Key
    doStuff(kvp.Value)
}

Auch hier können Sie nur den Wert benötigen. LINQ bietet auch eine kurze Lösung:

  • iterieren direkt auf dem Wert (erlaubt es item zu nennen, besser lesbar als kvp.Value)
  • aber durch die Tasten sortiert

Hier ist sie:

foreach (var item in items.OrderBy(kvp => kvp.Key).Select(kvp => kvp.Value))
{
    doStuff(item)
}

Es gibt viele weitere realen Anwendungsfall Sie aus diesen Beispielen tun. Wenn Sie nicht über einen bestimmten Auftrag benötigen, nur Stick auf die „einfachste Art und Weise“ (siehe oben)!

würde ich sagen, foreach der normale Weg ist, obwohl es hängt natürlich auf das, was Sie suchen

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

Ist das, was Sie suchen?

Sie können auch versuchen, diese auf große Wörterbücher für Multithreading-Verarbeitung.

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

Es gibt viele Möglichkeiten. Mein persönlicher Favorit ist von KeyValuePair

Dictionary<string, object> myDictionary = new Dictionary<string, object>();
// Populate your dictionary here

foreach (KeyValuePair<string,object> kvp in myDictionary)
{
     // Do some interesting things
}

Sie können auch die Schlüssel und Werte Kollektionen verwenden

Ich schätze diese Frage schon viele Antworten hatte, aber ich wollte in einer wenig Forschung werfen.

Iterieren über ein Wörterbuch kann langsam sein, eher, wenn sie mit Iterieren über etwas wie ein Array verglichen. In meinen Tests nahm eine Iteration über ein Array 0.015003 Sekunden lang während einer Iteration über ein Wörterbuch (mit der gleichen Anzahl von Elementen) nahm 0,0365073 Sekunden, die so lange das 2,4-fache ist! Obwohl ich viel größere Unterschiede gesehen. Zum Vergleich wurde eine Liste irgendwo dazwischen in 0.00215043 Sekunden.

Das ist jedoch wie Äpfel und Birnen vergleichen. Mein Punkt ist, dass über Wörterbücher Iterieren langsam ist.

Wörterbücher sind für Lookups optimiert, so mit diesem Gedanken habe ich zwei Methoden erstellt haben. Man tut einfach eine foreach, die anderen iteriert die Tasten dann schaut nach oben.

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 Schlüssel und iteriert über sie lädt statt (ich auch versuchte die Schlüssel in einen String 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";
}

Mit diesem Beispiel wird der normale foreach Test nahm 0.0310062 und die Tasten Version nahm 0,2205441. alle Schlüssel zu laden und alle Lookups iterieren ist eindeutig viel langsamer!

Für eine Endprüfung ich meine Iteration zehnmal durchgeführt habe, um zu sehen, ob es irgendwelche Vorteile sind die Schlüssel hier mit (von diesem Punkt war ich nur neugierig):

Hier ist die RunTest Methode, wenn das hilft Ihnen zu visualisieren, was los ist.

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 ist der normale foreach Lauf nahm 0.2820564 Sekunden (etwa zehnmal länger als eine einzige Iteration nahm - wie man erwarten würde). Die Iteration über die Tasten nahm 2.2249449 Sekunden.

Edited hinzufügen: einige der anderen Antworten zu lesen hat mich fragen, was passiert, wenn ich statt Wörterbuch verwendet Wörterbuch passieren würde. In diesem Beispiel hat das Array 0.0120024 Sekunden die Liste 0.0185037 Sekunden, und das Wörterbuch 0.0465093 Sekunden. Es ist zu erwarten, dass der Datentyp macht einen Unterschied, wie viel langsamer das Wörterbuch ist.

Was sind meine Schlussfolgerungen

  • Vermeiden Sie über ein Wörterbuch laufen, wenn Sie können, sie über ein Array als Iterieren mit den gleichen Daten in sie wesentlich langsamer sind.
  • Wenn Sie über einen Wörterbuch iterieren wähle nicht versuchen, zu klug zu sein, obwohl langsamer Sie viel schlimmer als mit der Standard-foreach Methode tun könnten.

C # 7.0 eingeführt Deconstructors und wenn Sie mit .NET Core 2.0 + Anwendung, umfassen die Struktur KeyValuePair<> bereits eine Deconstruct() für Sie. So 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}");
}

 image description hier

Sie schlug vor, unter iterieren

Dictionary<string,object> myDictionary = new Dictionary<string,object>();
//Populate your dictionary here

foreach (KeyValuePair<string,object> kvp in myDictionary) {
    //Do some interesting things;
}

FYI, ist foreach nicht, wenn der Wert vom Typ Objekt ist.

Mit .NET Framework 4.7 kann man verwenden Zersetzung

var fruits = new Dictionary<string, int>();
...
foreach (var (fruit, number) in fruits)
{
    Console.WriteLine(fruit + ": " + number);
}

Um diesen Gutscheincode bei niederem C # Versionen, fügt System.ValueTuple NuGet package und schreibt irgendwo

public static class MyExtensions
{
    public static void Deconstruct<T1, T2>(this KeyValuePair<T1, T2> tuple,
        out T1 key, out T2 value)
    {
        key = tuple.Key;
        value = tuple.Value;
    }
}

Einfachste Form ein Wörterbuch iterieren:

foreach(var item in myDictionary)
{ 
    Console.WriteLine(item.Key);
    Console.WriteLine(item.Value);
}

Mit C # 7 , fügen Sie diese Erweiterungsmethode für jedes Projekt Ihrer Lösung:

public static class IDictionaryExtensions
{
    public static IEnumerable<(TKey, TValue)> Tuples<TKey, TValue>(
        this IDictionary<TKey, TValue> dict)
    {
        foreach (KeyValuePair<TKey, TValue> kvp in dict)
            yield return (kvp.Key, kvp.Value);
    }
}


Und verwenden Sie diese einfache Syntax

foreach (var(id, value) in dict.Tuples())
{
    // your code using 'id' and 'value'
}


Oder diese, wenn Sie es vorziehen

foreach ((string id, object value) in dict.Tuples())
{
    // your code using 'id' and 'value'
}


Anstelle der traditionellen

foreach (KeyValuePair<string, object> kvp in dict)
{
    string id = kvp.Key;
    object value = kvp.Value;

    // your code using 'id' and 'value'
}


Die Erweiterung Methode wandelt die KeyValuePair Ihrer IDictionary<TKey, TValue> in eine stark typisierte tuple, so dass Sie diese neue komfortable Syntax verwenden.

Es wandelt -just- die erforderlichen Wörterbucheinträge tuples, so dass es nicht konvertiert nicht das ganze Wörterbuch tuples, so gibt es keine Performance-Bedenken, dass im Zusammenhang.

Es gibt eine nur geringe Kosten für die Erweiterung Verfahren zum Erzeugen eines tuple im Vergleich mit dem KeyValuePair direkt aufrufen, die kein Problem sein sollte, wenn Sie die KeyValuePair Eigenschaften Key und Value neue Schleifenvariablen ohnehin zuweisen.

In der Praxis werde diese neue Syntax paßt sehr gut für die meisten Fälle, mit Ausnahme von Low-Level-Ultra High Performance-Szenarien, wo man noch die Möglichkeit hat, einfach nicht an dieser bestimmten Stelle verwendet werden.

Check this out: MSDN Blog - Neue Funktionen in C # 7

Manchmal nur, wenn Sie die Werte muss aufgezählt werden, verwenden Sie den Wert Sammlung Wörterbuch:

foreach(var value in dictionary.Values)
{
    // do something with entry.Value only
}

von diesem Post berichtet, das besagt es die schnellste Methode ist: http://alexpinsker.blogspot.hk/2010 /02/c-fastest-way-to-iterate-over.html

Ich fand diese Methode in der Dokumentation für die Dictionary Klasse auf MSDN:

foreach (DictionaryEntry de in myDictionary)
{
     //Do some stuff with de.Value or de.Key
}

Dies war die einzige, den ich konnte richtig in einer Klasse erhalten funktionieren, die von der Dictionary geerbt.

Ich werde den Vorteil 4.0+ .NET nehmen und bieten eine aktualisierte Antwort auf die ursprünglich angenommen ein:

foreach(var entry in MyDic)
{
    // do something with entry.Value or entry.Key
}

Der Standardweg ein Wörterbuch iterieren, nach offizieller Dokumentation auf MSDN ist:

foreach (DictionaryEntry entry in myDictionary)
{
     //Read entry.Key and entry.Value here
}

Wie von C # 7 können Sie Objekte in Variablen dekonstruieren. Ich glaube, dass dies der beste Weg, um ein Wörterbuch iterieren.

Beispiel:

Erstellen Sie eine Erweiterungsmethode auf KeyValuePair<TKey, TVal>, die es dekonstruiert:

public static void Deconstruct<TKey, TVal>(this KeyValuePair<TKey, TVal> pair, out TKey, out TVal val)
{
   key = pair.Key;
   val = pair.Value;
}

jede Dictionary<TKey, TVal> auf die folgende Weise durchlaufen

// Dictionary can be of any types, just using 'int' and 'string' as examples.
Dictionary<int, string> dict = new Dictionary<int, string>();

// Deconstructor gets called here.
foreach (var (key, value) in dict)
{
   Console.WriteLine($"{key} : {value}");
}

Wenn sagen wir, Sie standardmäßig die Werte Sammlung iterieren, ich glaube, Sie IEnumerable implementieren <>, wobei T die Art der Werte Objekt im Wörterbuch enthalten ist, und „dies“ ein Wörterbuch ist.

public new IEnumerator<T> GetEnumerator()
{
   return this.Values.GetEnumerator();
}
var dictionary = new Dictionary<string, int>
{
    { "Key", 12 }
};

var aggregateObjectCollection = dictionary.Select(
    entry => new AggregateObject(entry.Key, entry.Value));

Ich wollte nur meine 2 Cent hinzufügen, da die meisten Antworten auf foreach-Schleife beziehen. Bitte nehmen Sie einen Blick auf den folgenden Code:

Dictionary<String, Double> myProductPrices = new Dictionary<String, Double>();

//Add some entries to the dictionary

myProductPrices.ToList().ForEach(kvP => 
{
    kvP.Value *= 1.15;
    Console.Writeline(String.Format("Product '{0}' has a new price: {1} $", kvp.Key, kvP.Value));
});

altought dies einen zusätzlichen Aufruf von ‚.ToList ()‘ fügt hinzu, es könnte eine leichte Leistungsverbesserung (wie hier darauf hingewiesen, foreach vs someList.Foreach () {} ), espacially bei großen Wörterbücher und läuft parallel arbeiten, ist keine Option / wird keinen Effekt haben überhaupt.

Beachten Sie auch, dass Sie nicht in der Lage sein, Werte zu der ‚Wert‘ in einer foreach-Schleife Eigenschaft zuweisen. Auf der anderen Seite, werden Sie den ‚Schlüssel‘ der Lage sein, auch zu manipulieren, möglicherweise Sie in Schwierigkeiten zur Laufzeit zu bekommen.

Wenn Sie wollen einfach nur von Schlüsseln und Werten „lesen“, könnten Sie auch IEnumerable.Select () verwenden.

var newProductPrices = myProductPrices.Select(kvp => new { Name = kvp.Key, Price = kvp.Value * 1.15 } );

Ich schrieb eine Erweiterung Schleife über ein Wörterbuch.

public static class DictionaryExtension
{
    public static void ForEach<T1, T2>(this Dictionary<T1, T2> dictionary, Action<T1, T2> action) {
        foreach(KeyValuePair<T1, T2> keyValue in dictionary) {
            action(keyValue.Key, keyValue.Value);
        }
    }
}

Dann können Sie anrufen

myDictionary.ForEach((x,y) => Console.WriteLine(x + " - " + y));

Ich weiß, dass dies eine sehr alte Frage, aber ich erstellt einige Erweiterungsmethoden, die nützlich sein könnten:

    public static void ForEach<T, U>(this Dictionary<T, U> d, Action<KeyValuePair<T, U>> a)
    {
        foreach (KeyValuePair<T, U> p in d) { a(p); }
    }

    public static void ForEach<T, U>(this Dictionary<T, U>.KeyCollection k, Action<T> a)
    {
        foreach (T t in k) { a(t); }
    }

    public static void ForEach<T, U>(this Dictionary<T, U>.ValueCollection v, Action<U> a)
    {
        foreach (U u in v) { a(u); }
    }

So kann ich Code wie folgt schreiben kann:

myDictionary.ForEach(pair => Console.Write($"key: {pair.Key}, value: {pair.Value}"));
myDictionary.Keys.ForEach(key => Console.Write(key););
myDictionary.Values.ForEach(value => Console.Write(value););

Wörterbuch Es ist eine generische Auflistung Klasse in c # und speichert die Daten in dem Schlüsselwert format.Key muss eindeutig sein, und es kann nicht null sein, während Wert doppelt sein kann und null.As jedes Element in dem Wörterbuch als KeyValuePair behandelt Struktur einen Schlüssel und seinen Wert darstellt. und daher sollten wir den Elementtyp KeyValuePair nehmen während der Iteration des Elements. Im Folgenden finden Sie das Beispiel.

Dictionary<int, string> dict = new Dictionary<int, string>();
dict.Add(1,"One");
dict.Add(2,"Two");
dict.Add(3,"Three");

foreach (KeyValuePair<int, string> item in dict)
{
    Console.WriteLine("Key: {0}, Value: {1}", item.Key, item.Value);
}

zusätzlich zu den ranghöchsten Beiträge, wo es eine Diskussion zwischen der Verwendung von

foreach(KeyValuePair<string, string> entry in myDictionary)
{
    // do something with entry.Value or entry.Key
}

oder

foreach(var entry in myDictionary)
{
    // do something with entry.Value or entry.Key
}

vollständigste Folgendes ist, weil Sie den Wörterbuchtyp aus der Initialisierung sehen können, KVP ist KeyValuePair

var myDictionary = new Dictionary<string, string>(x);//fill dictionary with x

foreach(var kvp in myDictionary)//iterate over dictionary
{
    // do something with kvp.Value or kvp.Key
}

Wörterbücher sind spezielle Listen, während jeder Wert in der Liste einen Schlüssel hat    Das ist auch eine Variable. Ein gutes Beispiel für einen Wörterbuch ist ein Telefonbuch.

   Dictionary<string, long> phonebook = new Dictionary<string, long>();
    phonebook.Add("Alex", 4154346543);
    phonebook["Jessica"] = 4159484588;

Beachten Sie, dass, wenn ein Wörterbuch zu definieren, müssen wir eine generische zur Verfügung zu stellen    Definition mit zwei Arten - die Art des Schlüssels und der Art des Wertes. In diesem Fall ist der Schlüssel ein String während des Wertes eine ganze Zahl ist.

Darüber hinaus gibt es zwei Möglichkeiten, um einen einzelnen Wert zu dem Wörterbuch hinzufügen, entweder mit Hilfe der Klammern Operator oder die Add-Methode verwendet wird.

Um zu überprüfen, ob ein Wörterbuch einen bestimmten Schlüssel in der es hat, können wir die ContainsKey Methode verwenden:

Dictionary<string, long> phonebook = new Dictionary<string, long>();
phonebook.Add("Alex", 415434543);
phonebook["Jessica"] = 415984588;

if (phonebook.ContainsKey("Alex"))
{
    Console.WriteLine("Alex's number is " + phonebook["Alex"]);
}

Um ein Element aus einem Wörterbuch zu entfernen, können wir die Remove-Methode verwenden. Entfernen ein Element aus einem Wörterbuch von seinem Schlüssel ist schnell und sehr effizient. Wenn ein Element aus einer Liste zu entfernen seinen Wert verwendet wird, der Prozess ist langsam und ineffizient, im Gegensatz zu der Wörterbuch entfernen Funktion.

Dictionary<string, long> phonebook = new Dictionary<string, long>();
phonebook.Add("Alex", 415434543);
phonebook["Jessica"] = 415984588;

phonebook.Remove("Jessica");
Console.WriteLine(phonebook.Count);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top