2010-09-16 18 views
7

¿Puede aconsejarme sobre cómo consultar un diccionario de diccionarios y/o un diccionario de listas?¿Quieres consultar un diccionario de diccionarios?

private Dictionary<string, Dictionary<DateTime, double>> masterDict= new Dictionary<string, Dictionary<DateTime, double>>(); 

Private Dictionary<string, List<DateTime>> masterList= new Dictionary<string, List<DateTime>>(); 

sé si hago lo siguiente, me sale una lista de los diccionarios contenidas en masterDict, pero no estoy seguro de cómo llegar a los valores de esos diccionarios.

foreach (var kvp in masterDictMethod()) 
     { 
      Console.WriteLine("Key = {0}, Value = {1}", 
       kvp.Key, kvp.Value); 
     } 

Gracias por mirar;)

Respuesta

5

En que forEach kvp.Value es el diccionario interior de cada entrada masterDict es decir Dictionary<DateTime, double>

lo tanto, sólo foreach también sobre kvp.Value y usted obtener los valores internos.

p. Ej.

foreach (var kvp1 in masterDictMethod()) 
{ 
    Console.WriteLine("Key = {0}, Inner Dict:", kvp1.Key); 
    foreach (var kvp2 in kvp1.Value) 
    { 
     Console.WriteLine("Date = {0}, Double = {1}", kvp2.Key, kvp2.Value); 
    } 
} 
+0

Perfecto. Gracias. – Brian

0
foreach (var key in masterDict.Keys) 
{ 
    var nestedDict = masterDict[key]; 
} 
+0

Sería mejor hacer: 'foreach (var kv en masterDict) {/ * trabajar con kv.Value - el dict interno. * /} '. Esto guarda la búsqueda interna ('Dictionary ' implementa 'IEnumerable >'.) – Richard

1

Ésta es:

var masterDictionary = new Dictionary<string, Dictionary<DateTime, double>>(); 

var query = 
    from kvp1 in masterDictionary 
    from kvp2 in kvp1.Value 
    select new {TheString = kvp1.Key, TheDate = kvp2.Key, TheDouble = kvp2.Value }; 

foreach(var x in query) 
{ 
    Console.WriteLine("{0} {1} {2}", x.TheString, x.TheDate, x.TheDouble); 
} 

Y luego el otro es:

var masterList= new Dictionary<string, List<DateTime>>(); 

var query = 
    from kvp in masterList 
    from val in kvp.Value 
    select new {TheString = kvp.Key, TheDate = val); 

foreach(var x in query) 
{ 
    Console.WriteLine("{0} {1}", x.TheString, x.TheDate); 
} 
+0

¿Sabe hacerlo por métodos de extensión en lugar de una consulta? – mggSoft

+1

@MGG_Soft Sí, estás buscando una de las sobrecargas de Enumerable.SelectMany –

0

Usted preguntó acerca de las listas, diccionarios y diccionarios que contienen otros diccionarios.

que tenían un tema similar hace poco, cuando yo quería tener un diccionario consultable (es decir, un método de extensión que permite transmitir una expresión de consulta como parámetro lambda), que se puede utilizar como:

var result = myDictionary.QueryDictionary(w => myList.Any(a => a == w.Key)); 

El El propósito de esta línea de código es verificar si alguna clave del diccionario está contenida en myList.

Así que lo que hice es esto, escribí el siguiente método de extensión:

// extension method using lambda parameters 
public static Dictionary<string, T> QueryDictionary<T>(
    this Dictionary<string, T> myDict, 
    Expression<Func<KeyValuePair<string,T>, bool>> fnLambda) 
{ 
    return myDict.AsQueryable().Where(fnLambda).ToDictionary(t => t.Key, t => t.Value); 
} 

Puede ser utilizado para todos los diccionarios que tiene las llaves de tipo string y artículos de cada tipo de objeto T.

Ahora se puede escribir fácilmente consultas pasando una expresión lambda, como en el siguiente ejemplo:

var list1 = new List<string>() { "a", "b" }; 
var myDict = new Dictionary<string, object>(); 
myDict.Add("a", "123"); myDict.Add("b", "456"); myDict.Add("c", "789"); 

var result = myDict.QueryDictionary(w => list1.Any(a => a == w.Key)); 

El resultado va a contener elementos a y b, ya que están contenidos en la lista1.

También puede consultar un diccionario de diccionarios, aquí hay un ejemplo C# para LinqPad, pero se puede utilizar como una aplicación de consola, así (basta con comentar las declaraciones .Dump() y reemplazarlos por Console.WriteLine(...) declaraciones):

void Main() 
{ 
    // *** Set up some data structures to be used later *** 
    var list1 = new List<string>() { "a", "b", "d" }; // a list 
    var myDict = new Dictionary<string, object>(); // the dictionary 
    myDict.Add("a", "123"); myDict.Add("b", "456"); myDict.Add("c", "789"); 

    var myDict2 = new Dictionary<string, object>(); // 2nd dictionary 
    myDict2.Add("a", "123"); myDict2.Add("b", "456"); myDict2.Add("c", "789"); 

    myDict.Add("d", myDict2); // add 2nd to first dictionary 

    // *** 1. simple query on dictionary myDict *** 
    var q1 = myDict.QueryDictionary(w => list1.Any(a => a == w.Key)); 
    q1.Dump(); 

    // *** 2. query dictionary of dictionary (q3 contains result) *** 
    var q2 = 
     (Dictionary<string, object>)q1.QueryDictionary(w => w.Key.Equals("d")).First().Value; 
    var q3 = q2.QueryDictionary(w => w.Key.Equals("b")); 
    q3.Dump(); 
} 

// *** Extension method 'QueryDictionary' used in code above *** 
public static class Extensions 
{ 
    public static Dictionary<string, T> QueryDictionary<T>(
     this Dictionary<string, T> myDict, 
     Expression<Func<KeyValuePair<string, T>, bool>> fnLambda) 
    { 
     return myDict.AsQueryable().Where(fnLambda).ToDictionary(t => t.Key, t => t.Value); 
    } 
} 

Dado que esta solución es utilizar los genéricos, puede pasar cualquier expresión lambda como parámetro de búsqueda, por lo que es muy flexible.

Cuestiones relacionadas