2013-02-18 4 views
1

У меня есть класс C, который имеет список [B], а каждый имеет словарь [A, двойной]макс за единицу в списке элементов

нужно выбрать макс (дважды) в расчете на одну в настоящее время я делаю:

Dictionary<A,double> rtn = new Dictionary<A,double>(); 
foreach (var B in C.Bs) 
{ 
    foreach (var kvpA in B.A_list.Where(a => !rtn.Keys.ToList().Contains(a))) 
    { 
     rtn.Add(kvpA.Key, kvpA.Value); 
    } 
    foreach(var kvpA in B.A_list.Where(a => rtn.Keys.Contains(a) && a.Value>rtn[a])) 
    { 
     rtn[kvpA.Key] = kvpA.Value; 
    } 
} 
return rtn; 

Однако это выглядит довольно грязный, поэтому я пытаюсь построить лучший Linq запрос, но не могу понять синтаксис. любая помощь?

+2

_ "... max (int) per A ..." _ О чем вы говорите? –

+0

'B имеет словарь [A, double]' - это свойство 'A_list'? Если это так, этот код не компилируется: 'B.A_list.Where (a => rtn.Keys.Contains (a)' – GolfWolf

+0

вы можете показать определения для классов 'A',' B' и 'C'? – GolfWolf

ответ

5

Я предполагаю, что max (int) вы просто означали «max», как в максимальном двойном на каждый уникальный A по всему A_Lists, которые на самом деле являются словарями.

Во всяком случае, вы можете сделать все это в три этапа в одном операторе LINQ:

  1. Свернуть все ключевые пары значений с помощью SelectMany
  2. Группа по уникальной А с помощью GroupBy
  3. Возьмите максимальный двойной пер ключ с помощью ToDictionary

Где c является экземпляром класса C:

var dct = c.Bs.SelectMany(x => x.A_List) 
      .GroupBy(p => p.Key, p => p.Value) 
      .ToDictionary(g => g.Key, g => g.Max()); 

Вы также можете использовать ToLookup вместо ToDictionary, которая позволила бы получить в IEnumerable итератор над теми же [A, double] кортежей, как материализуется ToDictionary.

+1

+1 вам не нужно 'Select (y => y)' внутри 'SelectMany', но в противном случае это именно то, что я придумал – juharr

+0

@juharr Хорошо, спасибо. –

+0

Спасибо, что выглядит так, как я был после – MikeT

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