2013-02-09 87 views
0

基本上,我有一个小程序,我想在对象列表上执行一系列排序。每种排序都应该在对象的不同属性上进行操作,并遵守前一种排序所产生的排序。这是我到目前为止有:如何使用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做这件事的最佳方式是什么?理想情况下,我希望解决方案能够根据需要扩展和支持尽可能多的链接排序,每种排序都会生成一组“分组”,以便下一个分拣程序必须对其排序进行本地化。

+4

你看着ThenBy()做链接? – Jay 2013-02-09 20:30:24

+1

你应该像上面提到的那样使用'ThenBy',但如果你感兴趣的话:你有没有注意到这两位43岁的孩子是按字母顺序排列的?这可能只是一个巧合,但事实并非如此。这是因为'Enumerable.OrderBy'执行一个稳定的排序,这意味着任何两个相同年龄的记录按照它们出现在底层枚举中的顺序进行排序,该枚举按名称排序。这导致了另一种解决方案:'.OrderBy(p => p.Age).OrderBy(p => p.Name)'。 – hvd 2013-02-09 21:47:05

回答