c# recorrer dictionary - ¿Cuál es la mejor manera de iterar sobre un diccionario?




12 Answers

Si está intentando usar un Diccionario genérico en C #, como si usara una matriz asociativa en otro idioma:

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

O, si solo necesita iterar sobre la colección de claves, use

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

Y por último, si solo te interesan los valores:

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

(Tenga en cuenta que la palabra clave var es una característica opcional de C # 3.0 y superior, también puede usar el tipo exacto de sus claves / valores aquí)

pair access search

He visto algunas formas diferentes de iterar sobre un diccionario en C #. ¿Hay una forma estándar?




Depende de si buscas las claves o los valores ...

Desde el Dictionary(TKey, TValue) MSDN Dictionary(TKey, TValue) Descripción de la clase:

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



Yo diría que foreach es la forma estándar, aunque obviamente depende de lo que estés buscando

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

¿Es eso lo que estás buscando?




Hay un montón de opciones. Mi favorito personal es por KeyValuePair

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

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

También puedes utilizar las colecciones de claves y valores.




Con .NET Framework 4.7 se puede usar la descomposición

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

Para hacer que este código funcione en versiones de C # más bajas, agregue el System.ValueTuple NuGet package y escriba en algún lugar

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



La forma más simple de iterar un diccionario:

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



Usando C # 7 , agregue este método de extensión a cualquier proyecto de su solución:

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


Y usa esta sintaxis simple

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


O éste, si lo prefieres.

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


En lugar de lo tradicional.

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

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


El método de extensión transforma el KeyValuePair de su IDictionary<TKey, TValue> en una tuple fuertemente IDictionary<TKey, TValue> , lo que le permite utilizar esta nueva sintaxis cómoda.

Convierte, simplemente, las entradas requeridas del diccionario en tuples , por lo que NO convierte todo el diccionario en tuples , por lo que no hay problemas de rendimiento relacionados con eso.

Hay un solo costo menor que llama al método de extensión para crear una tuple en comparación con el uso de KeyValuePair directamente, lo que NO debería ser un problema si está asignando la Key y el Value propiedades de KeyValuePair a nuevas variables de bucle.

En la práctica, esta nueva sintaxis se adapta muy bien para la mayoría de los casos, excepto en los escenarios de rendimiento ultraalto de bajo nivel, donde aún tiene la opción de simplemente no usarla en ese lugar específico.

Mira esto: MSDN Blog - Nuevas características en C # 7




Aprovecharé de .NET 4.0+ y proporcionaré una respuesta actualizada a la aceptada originalmente:

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



Por ejemplo, si desea iterar sobre la colección de valores de forma predeterminada, creo que puede implementar IEnumerable <>, donde T es el tipo de objeto de valores en el diccionario, y "este" es un Diccionario.

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



Escribí una extensión para recorrer un diccionario.

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

Entonces puedes llamar

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



además de los puestos de mayor rango donde hay una discusión entre el uso

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

o

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

el más completo es el siguiente porque puede ver el tipo de diccionario desde la inicialización, kvp es 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
}





Related