Parent{ List<Child> Children {get;set;} }
Child { int Age {get;set;} }
I would like to order the parents by the lowest age of their children, proceeding to the second or third child in the case of a tie.
The closest I've come is this, which only orders by the youngest child:
parents.OrderBy(p => p.Children.Min(c => c.Age))
This doesn't account for second (or third, etc) youngest in the case of a tie.
Given these 3 parents with corresponding child ages, I'd like them to come out in this order.
So what you're trying to do, at a conceptual level, is compare two sequences. Rather than trying to special case it for this specific sequence, we can simply write a comparer capable of comparing any two sequences.
It will go through the items in the sequence compare the items at the same position, and then if it finds a pair that aren't equal, it knows the result.
public class SequenceComparer<TSource> : IComparer<IEnumerable<TSource>>
{
private IComparer<TSource> comparer;
public SequenceComparer(IComparer<TSource> comparer = null)
{
this.comparer = comparer ?? Comparer<TSource>.Default;
}
public int Compare(IEnumerable<TSource> x, IEnumerable<TSource> y)
{
return x.Zip(y, (a, b) => comparer.Compare(a, b))
.Where(n => n != 0)
.DefaultIfEmpty(x.Count().CompareTo(y.Count()))
.First();
}
}
Now we can simply use this comparer when calling OrderBy
:
var query = parents.OrderBy(parent => parent.Children
.OrderBy(child => child.Age)
.Select(child => child.Age)
, new SequenceComparer<int>());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With