2010-09-16 2 views
7

Пожалуйста, можете ли вы посоветовать мне, как запросить словарь словарей и/или словарь списка?Запрос словаря словарей?

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

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

Я знаю, что если я делаю следующее, я получаю список словарей, содержащиеся в masterDict, но я не уверен, как получить при значениях этих словарей.

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

Спасибо для смотреть;)

ответ

5

В вы Foreach kvp.Value это внутренний словарь каждой записи masterDict т.е. Dictionary<DateTime, double>

Так, только Foreach также над kvp.Value и вы получить внутренние значения.

например.

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

Отлично. Спасибо. – Brian

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

Было бы лучше сделать: 'foreach (var kv in masterDict) {/ * работать с kv.Value - внутренний dict. * /} '. Это сохраняет внутренний поиск ('Dictionary ' реализует 'IEnumerable >'.) – Richard

1

Это одно:

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

А потом другая является:

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

Знаете ли вы, что это делают с помощью методов расширения вместо запроса? – mggSoft

+1

@MGG_Soft Да, вы ищете одну из перегрузок Enumerable.SelectMany –

0

Вы спрашивали про списки, словари и словари, содержащие другие словари.

У меня был похожая тема в последнее время, где я хотел бы иметь запрашиваемый словарь (т.е. метод расширения, который позволяет передать выражение запроса в качестве параметра лямбды), который можно использовать как:

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

Цель этой строки кода - проверить, содержится ли какой-либо ключ словаря в myList.

Так что я сделал это, я написал следующий метод расширения:

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

Он может быть использован для каждого словаря, который имеет ключи типа string и элементов каждого типа объекта T.

Теперь вы можете легко писать запросы, передавая лямбда-выражения, как показано в следующем примере:

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

Результат будет содержать пункты а и б, поскольку они содержатся в list1.

Вы также можете запросить словарь словарей, вот пример C# для LinqPad, но он может быть использован в качестве консольного приложения, а также (только закомментируйте .Dump() заявления и заменить их Console.WriteLine(...) заявления):

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

Поскольку это решение использует дженерики, то вы можете передать любое выражение лямбда в качестве параметра поиска, так что это очень гибкая.

Смежные вопросы