:)
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
};
Мне нравится этот вопрос, потому что все мелкие детали (некоторые редко используются) требуются для ответа.
Max = g.Max(kvp => kvp.Value),
Total = g.Sum(kvp => kvp.Value)
Выполнить несколько объединений в группе просто, но сложно, если вы не знаете, как.
select a into b
Этот пункт берет все, что произошло раньше, и начинает новый запрос с целью. Без него мне пришлось бы начать новый запрос, подобный этому:
var A = ... select a
var B = from b in A
Важно отметить, что предложение select into
удаляет kvp
и g
из области видимости.
from b in source
from a in b.A //SelectMany
Эта "распаковка" дочерней коллекции превращает мой запрос о b в запрос о a. В отличие от стандартной перегрузки Enumerable.SelectMany, родительский элемент (b
) остается в области видимости.
where x.Value != ag.Max
Сравнение имущества ребенка со свойством родителя? Восхитительный. Важно помнить, что нужно выделять where
в любое время, когда вы хотите отфильтровать, даже если вы только что сгруппировались (HAVING
) нет.