2017-02-20 22 views
1

У меня есть немного кода на C#, который создает новый анонимный тип (коллекция). Записи в коллекции отличаются только по Child.Value. То, что я пытаюсь достичь, - уменьшить количество пар родитель-ребенок без дочерних дубликатов, получив пары родитель-ребенок с наивысшим значением для каждого ребенка в каждом родителе. Дети отличаются от Id ребенка.Отфильтровать коллекцию анонимного типа

var familyPairs = family 
     .SelectMany(parent => parent.Children, (parent, child) => 
       new { 
        Parent = parent, 
        Child = child 
        }) 
     .OrderByDescending(pair => pair.Child.Value); 

ответ

2

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

family.Select(p => new { 
    Parent = p, 
    Child = p.Children.OrderByDescending(c => c.Value).FirstOrDefault() 
}) 

Или, если вы не хотите пар для родителей без детей - отфильтровывать ребенок бесплатно родители:

family.Where(p => p.Children.Any()).Select(p => new { 
    Parent = p, 
    Child = p.Children.OrderByDescending(c => c.Value).First() 
}) 

После обновления вашего получается, что вам нужно SelectMany, но вы должны группировать детей по идентификатору и выбрать из каждой группы детей со значением макс:

family.SelectMany(
    p => p.Children.GroupBy(c => c.Id) 
        .Select(g => g.OrderByDescending(c => c.Value).First()), 
    (p,c) => new { Parent = p, Child = c }) 
+0

Я постараюсь его. :) –

+0

Извините, я отредактировал мой вопрос, если вы что-нибудь придумаете о редактировании. Но я все еще попытаюсь это сделать :) –

+0

@ CeylanMumunKocabaş, это не ясно из вашего редактирования - если у вас есть несколько записей для одного и того же ребенка в списке детей родителей, как вы отличаете двух разных детей? –

2

Если вы хотите только максимальное ребенка, сортировка является пустой тратой времени (п журнал п операций для списка детей). Вместо этого вы должны использовать метод расширения Aggregate() для повторения каждого списка детей один раз, чтобы получить максимальное значение с ребенком.

family.Select(p => new { 
Parent = p, 
Child = p.Children.Aggregate((c1, c2) => c1.Value > c2.Value ? c1 : c2)}) 

См: How can I get LINQ to return the object which has the max value for a given property?

+0

Кроме того, я должен указать, что если несколько детей имеют максимальное значение, между операторами> и> = существует большая разница. Оператор> выбирает последний ребенок с максимальным значением, а> = выбирает первый. – plushpuffin