Bạn có thể sử dụng ThenBy
và lấy 2 và trẻ em 3. Tuy nhiên, đó không phải là khả năng mở rộng, do đó, nó phụ thuộc vào nhu cầu của impl
Nếu bạn muốn một cái gì đó mạnh mẽ hơn, bạn có thể làm như sau. Nó sẽ làm việc cho trường hợp cụ thể này. Tôi sẽ xem liệu tôi có thể tối ưu hóa nó để được chung chung hơn mặc dù :)
public static class myExt
{
public static List<Parent> OrderByWithTieBreaker(this List<Parent> parents, int depth = 0)
{
if (depth > parents[0].Children.Count())
return parents;
var returnedList = new List<Parent>();
Func<Parent, int> keySelector = x =>
{
IEnumerable<Child> enumerable = x.Children.OrderBy(y => y.Age).Skip(depth);
if (!enumerable.Any())
return 0; //If no children left, then return lowest possible age
return enumerable.Min(z => z.Age);
};
var orderedParents = parents.OrderBy(keySelector);
var groupings = orderedParents.GroupBy(keySelector);
foreach (var grouping in groupings)
{
if (grouping.Count() > 1)
{
var innerOrder = grouping.ToList().OrderByWithTieBreaker(depth + 1);
returnedList = returnedList.Union(innerOrder).ToList();
}
else
returnedList.Add(grouping.First());
}
return returnedList;
}
}
[TestFixture]
public class TestClass
{
public class Parent { public string Name { get; set; } public List<Child> Children { get; set; } }
public class Child { public int Age {get;set;} }
[Test]
public void TestName()
{
var parents = new List<Parent>
{
new Parent{Name="P3", Children = new List<Child>{new Child{Age=1}, new Child{Age=3}, new Child{Age=6}, new Child{Age=7}}},
new Parent{Name="P4", Children = new List<Child>{new Child{Age=1}, new Child{Age=3}, new Child{Age=6}, new Child{Age=7}}},
new Parent{Name="P2", Children = new List<Child>{new Child{Age=1}, new Child{Age=3}, new Child{Age=6}}},
new Parent{Name="P1", Children = new List<Child>{new Child{Age=1}, new Child{Age=2}, new Child{Age=7}}},
new Parent{Name="P5", Children = new List<Child>{new Child{Age=1}, new Child{Age=4}, new Child{Age=5}}}
};
var f = parents.OrderByWithTieBreaker();
int count = 1;
foreach (var d in f)
{
Assert.That(d.Name, Is.EqualTo("P"+count));
count++;
}
}
Nguồn
2013-12-12 19:36:27
thể trùng lặp của [Có cách nào tích hợp để so sánh IEnumerable (bởi các yếu tố của họ)?] (Http://stackoverflow.com/questions/2811725/is-there-a-built-in-way-to-compare-ienumerablet-by-their-elements) –
Cụ thể, bạn có thể sử dụng cách triển khai từ đó như một phương thức 'So sánh' như như vậy: 'parents.OrderBy (p => p.Children.Select (x => x.Age) .ToList(), new SequenceComparer())' (trong đó 'SequenceComparer .Compare' là việc thực hiện tại liên kết đó) –