recorrer - search in dictionary c#




¿Cuál es la mejor manera de iterar sobre un diccionario? (17)

A partir de C # 7, puede deconstruir objetos en variables. Creo que esta es la mejor manera de iterar sobre un diccionario.

Ejemplo:

Cree un método de extensión en KeyValuePair<TKey, TVal> que lo KeyValuePair<TKey, TVal> :

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

Iterar sobre cualquier Dictionary<TKey, TVal> de la siguiente manera

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

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



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
}

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

En algunos casos, es posible que necesite un contador que puede ser proporcionado por la implementación de bucle for. Para eso, LINQ proporciona ElementAt que habilita lo siguiente:

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

En general, pedir "la mejor manera" sin un contexto específico es como preguntar cuál es el mejor color.

Por un lado, hay muchos colores y no hay mejor color. Depende de la necesidad y, a menudo, del gusto.

Por otro lado, hay muchas maneras de iterar sobre un Diccionario en C # y no hay una mejor manera. Depende de la necesidad y, a menudo, del gusto.

Manera más sencilla

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

Si solo necesita el valor (permite llamarlo item , más legible que kvp.Value ).

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

Si necesita un orden específico

En general, los principiantes se sorprenden por el orden de enumeración de un Diccionario.

LINQ proporciona una sintaxis concisa que permite especificar el orden (y muchas otras cosas), por ejemplo:

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

Una vez más, es posible que sólo necesite el valor. LINQ también proporciona una solución concisa para:

  • iterar directamente en el valor (permite llamarlo item , más legible que kvp.Value )
  • pero ordenados por las llaves

Aquí está:

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

Hay muchos más casos de uso del mundo real que puede hacer a partir de estos ejemplos. Si no necesita una orden específica, simplemente siga la "manera más directa" (ver arriba).


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

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.


La forma más simple de iterar un diccionario:

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

Los diccionarios son listas especiales, mientras que cada valor en la lista tiene una clave que también es una variable. Un buen ejemplo de un diccionario es una guía telefónica.

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

Tenga en cuenta que al definir un diccionario, debemos proporcionar una definición genérica con dos tipos: el tipo de clave y el tipo de valor. En este caso, la clave es una cadena, mientras que el valor es un número entero.

También hay dos formas de agregar un solo valor al diccionario, ya sea usando el operador de corchetes o usando el método Agregar.

Para verificar si un diccionario tiene cierta clave, podemos usar el método ContainsKey:

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

Para eliminar un elemento de un diccionario, podemos utilizar el método Eliminar. Eliminar un elemento de un diccionario por su clave es rápido y muy eficiente. Al eliminar un elemento de una Lista utilizando su valor, el proceso es lento e ineficiente, a diferencia de la función Eliminar del diccionario.

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

phonebook.Remove("Jessica");
Console.WriteLine(phonebook.Count);

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


Solo quería agregar mi 2 centavo, ya que la mayoría de las respuestas se relacionan con foreach-loop. Por favor, eche un vistazo al siguiente código:

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

Si esto agrega una llamada adicional de '.ToList ()', puede haber una leve mejora en el rendimiento (como se indica aquí para cada vs vs. Lista.Para cada () {} ), especialmente cuando se trabaja con grandes diccionarios y se ejecuta en paralelo no Opción / no tendrá ningún efecto en absoluto.

Además, tenga en cuenta que no podrá asignar valores a la propiedad 'Valor' dentro de un bucle foreach. Por otro lado, también podrás manipular la 'Clave', posiblemente causando problemas en el tiempo de ejecución.

Cuando solo quiere "leer" Claves y valores, también puede usar IEnumerable.Select ().

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

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


Usted sugirió a continuación para iterar

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

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

Para su información, foreach no funciona si el valor es de tipo objeto.


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
}

Dictionary <TKey, TValue> Es una clase de colección genérica en c # y almacena los datos en el formato del valor clave. La clave debe ser única y no puede ser nula, mientras que el valor puede ser duplicado y nulo. Como cada elemento del diccionario es tratado como KeyValuePair <TKey, TValue> estructura que representa una clave y su valor. y por lo tanto deberíamos tomar el tipo de elemento KeyValuePair <TKey, TValue> durante la iteración del elemento. A continuación se muestra el ejemplo.

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

var dictionary = new Dictionary<string, int>
{
    { "Key", 12 }
};

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




loops