基本上,我有一个小程序,我想在对象列表上执行一系列排序。每种排序都应该在对象的不同属性上进行操作,并遵守前一种排序所产生的排序。这是我到目前为止有:如何使用IEnumerable连接分拣机,每台分拣机都遵守上一次生产的顺序?
class Program
{
static void Main(string[] args)
{
List<Person> people = new List<Person>();
people.Add(new Person { Name = "John", Age = 43 });
people.Add(new Person { Name = "Ringo", Age = 73 });
people.Add(new Person { Name = "John", Age = 32 });
people.Add(new Person { Name = "Paul", Age = 38 });
people.Add(new Person { Name = "George", Age = 16 });
people.Add(new Person { Name = "John", Age = 80 });
people.Add(new Person { Name = "Ringo", Age = 22 });
people.Add(new Person { Name = "Paul", Age = 64 });
people.Add(new Person { Name = "George", Age = 51 });
people.Add(new Person { Name = "George", Age = 27 });
people.Add(new Person { Name = "Ringo", Age = 5 });
people.Add(new Person { Name = "Paul", Age = 43 });
Print(Sort(people));
}
static IEnumerable<Person> Sort(IEnumerable<Person> people)
{
//order by name first, then order by age
return people.OrderBy(p => p.Name).OrderBy(p => p.Age);
}
static void Print(IEnumerable<Person> people)
{
foreach (Person p in people)
Console.WriteLine("{0} {1}", p.Name, p.Age);
}
class Person
{
public string Name {get; set;}
public int Age { get; set; }
}
}
这将产生以下的输出:
Ringo 5 George 16 Ringo 22 George 27 John 32 Paul 38 John 43 Paul 43 George 51 Paul 64 Ringo 73 John 80
但我想它产生这个输出:
George 16 George 27 George 51 John 32 John 43 John 80 Paul 38 Paul 43 Paul 64 Ringo 5 Ringo 22 Ringo 73
换句话说,我想要它通过Name
订购,然后在每个Name
内执行Age
的本地订购“组”。很显然,我迄今为止的方法并没有这样做,它只是执行两个链接OrderBy
's。
我可以用IEnumerable
做这件事的最佳方式是什么?理想情况下,我希望解决方案能够根据需要扩展和支持尽可能多的链接排序,每种排序都会生成一组“分组”,以便下一个分拣程序必须对其排序进行本地化。
你看着ThenBy()做链接? – Jay 2013-02-09 20:30:24
你应该像上面提到的那样使用'ThenBy',但如果你感兴趣的话:你有没有注意到这两位43岁的孩子是按字母顺序排列的?这可能只是一个巧合,但事实并非如此。这是因为'Enumerable.OrderBy'执行一个稳定的排序,这意味着任何两个相同年龄的记录按照它们出现在底层枚举中的顺序进行排序,该枚举按名称排序。这导致了另一种解决方案:'.OrderBy(p => p.Age).OrderBy(p => p.Name)'。 – hvd 2013-02-09 21:47:05