:)
var results =
from kvp in source
group kvp by kvp.Key.ToUpper() into g
select new
{
Group = g,
Max = g.Max(kvp => kvp.Value),
Total = g.Sum(kvp => kvp.Value)
} into ag
from x in ag.Group //SelectMany
where x.Value != ag.Max
//for the update to the question - note: possibly ambiguous
let correct = ag.Group.Where(y => y.Value == ag.Max).First().Key
select new
{
Key = x.Key,
Max = ag.Max,
Total = ag.Total,
Correct = correct
};
I trochę jak pytanie, ponieważ wszystkie małe części (niektóre są rzadko stosowane), które są wymagane, aby udzielić odpowiedzi.
Max = g.Max(kvp => kvp.Value),
Total = g.Sum(kvp => kvp.Value)
Wykonywanie wielu agregacje na grupie jest prosta, ale wymagająca jeśli nie wiesz jak to zrobić.
select a into b
Klauzula ta bierze wszystko, co wydarzyło się przed i rozpoczyna nowe zapytanie z celem. Bez niego musiałbym zacząć nową kwerendę tak:
var A = ... select a
var B = from b in A
Ważne jest, aby pamiętać, że klauzula select into
usuwa kvp
i g
z zakresu.
from b in source
from a in b.A //SelectMany
Ten „rozpakowaniu” z kolekcji dziecięcej zamienia moje zapytanie o B-tych w zapytaniu o tych. W przeciwieństwie do domyślnego przeciążenia Enumerable.SelectMany, pozostawia zakres macierzysty (b
).
where x.Value != ag.Max
Porównując własności dziecka z majątku rodzica? Zachwycający. Ważne jest, aby pamiętać o tym, aby wydzielać where
za każdym razem, gdy chcesz filtrować, nawet jeśli się zgrupowałeś (nie ma HAVING
).
Brzmi podejrzanie jak zadanie domowe. –
Lub pytanie do wywiadu ... praca domowa zazwyczaj nie wymaga "ToUpper" –
Żadnych chaps, zobaczysz z mojego profilu, że jestem trochę przeszłości zadanie domowe :) I naprawdę nie pro koder [już], tylko dla zabawy :) –