Ceylan Mumun Kocabaş
Ceylan Mumun Kocabaş

Reputation: 527

Filter anonymous type collection

I have some little C# code which creates new anonymous type (collection). Entries in the collection differ only by Child.Value. What i am trying to achieve is: reduce the count of the parent-child pairs without child duplicates by getting the parent-child pairs with the highest value for each children in every parent. The children are distinguished by child Id.

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

Upvotes: 1

Views: 701

Answers (2)

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236278

If you need single parent-child pair for each parent, then you can use simple select:

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

Or if you don't want pairs for parents without children - filter out child free parents:

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

After your update it turns out that you need SelectMany, but you need to group children by id and select from each group child with max value:

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

Upvotes: 2

plushpuffin
plushpuffin

Reputation: 311

If you want only the maximum child, sorting is a waste of time (n log n operations for the list of children). Instead, you should use the Aggregate() extension method to iterate through each list of children once to get the child with the maximum value.

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

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

Upvotes: 2

Related Questions