2012-03-21 25 views
1

我正在編寫通訊簿程序。我將每個人的詳細信息存儲在List<Person>中。我需要能夠按姓氏排序此列表(如果有關係,請使用名字)或郵編。按字母順序使用指定屬性對對象的通用列表進行排序

到目前爲止,我有這樣的:

public class Person 
{ 
    public string LastName { get; set; } 
    public string FirstName { get; set; } 
    public string PostCode { get; set; } 
    // etc.. 
} 

public class AddressBook 
{ 
    public List<Person> People { get; set; } 

    // asc: ascending or descending 
    // column: the property to use when sorting 
    //   (in my case either LastName or Postcode) 
    public void Sort(bool asc, string column) 
    { 
     // What should I put here? 
    } 

    // etc... 
} 

我已經使用ICompareIComparable接口嘗試,但我只是沒有得到它。

如何編寫Sort方法?

+0

您使用的是什麼版本的C#/ .NET? – 2012-03-21 11:39:10

+0

4.0我認爲..... – Jammerz858 2012-03-21 13:06:48

+0

我試圖清理你的問題,以便閱讀更容易。我希望沒關係。 – 2012-03-21 13:18:35

回答

3

您可以使用IComparer<T>實現:

public class PersonComparer : IComparer<Person> 
{ 
    private readonly bool _sortAscending; 
    private readonly string _columnToSortOn; 

    public PersonComparer(bool sortAscending, string columnToSortOn) 
    { 
     _sortAscending = sortAscending; 
     _columnToSortOn = columnToSortOn; 
    } 

    public int Compare(Person x, Person y) 
    { 
     if(x == null && y == null) return 0; 
     if(x == null) return ApplySortDirection(-1); 
     if(y == null) return ApplySortDirection(1); 

     switch(_columnToSortOn) 
     { 
      case "LastName": 
       return ApplySortDirection(SortByName(x, y)); 
       break; 
      case "PostCode": 
       return ApplySortDirection(SortByPostCode(x, y)); 
       break; 
      default: 
       throw new ArgumentOutOfRangeException(
        string.Format("Can't sort on column {0}", 
        _columnToSortOn)); 
     } 
    } 

    private int SortByPostCode(Person x, Person y) 
    { 
     return x.PostCode.CompareTo(y.PostCode); 
    } 

    private int SortByName(Person x, Person y) 
    { 
     var lastNameResult = x.LastName.CompareTo(y.LastName); 
     if(lastNameResult != 0) 
      return lastNameResult; 
     return x.FirstName.CompareTo(y.FirstName); 
    } 

    private int ApplySortDirection(int result) 
    { 
     return _sortAscending ? result : (result * -1); 
    } 
} 

你可以使用它在你的AddressBookSort方法這樣的班級,假設PeopleList<Person>

public void Sort(bool asc, string column) 
{ 
    People.Sort(new PersonComparer(asc, column)); 
} 

此代碼有使用就地排序的好處。

+0

布里爾!謝謝丹尼爾。 – Jammerz858 2012-03-21 12:59:55

+0

完美地工作。 AND ...(更好)我明白了...非常感謝! – Jammerz858 2012-03-21 13:00:34

+0

@ user1243505:不客氣。請不要忘記接受我的回答:[如何接受答案?](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work) – 2012-03-21 13:01:26

4

您可以嘗試使用LINQ擴展方法OrderByOrderByDescendingThenByThenByDescending

using System.Linq; 

// ... 

public void Sort(bool asc, string column) 
{ 
    switch (column) 
    { 
     case "LastName": 
      People = People.OrderBy(x => x.LastName).ThenBy(x => x.FirstName).ToList(); 
      break; 
     case "PostCode": 
      People = People.OrderBy(x => x.PostCode).ToList(); 
      break; 
     default: 
      // error handling 
    } 

    if (!asc) 
    { 
     People.Reverse(); 
    } 
} 

你也可以看看動態LINQ這將簡化該代碼。

+0

感謝您的回覆。正如我下面所說的,我需要更多地關注linq,因爲我不知道如何讓你的代碼對列表進行排序。儘管謝謝你的幫助。 – Jammerz858 2012-03-21 13:10:54

+0

@ user1243505:如果我是你,我會投資我的未來並學習LINQ。它更簡單,更易於使用。現在對自己的教育進行少量投資將長期爲您節省大量時間,並使您在將來成爲更有價值的程序員。但這是你的生活,你的職業生涯,你的選擇... – 2012-03-21 13:41:45

1

假設:

List<Person> personList; 

然後使用LINQ:

IEnumerable<Person> orderedByLastName = personList.OrderBy(p => p.LastName) 
+0

謝謝斯彭德,我明顯錯過了一些東西(需要做更多的閱讀linq),因爲這根本不適合我。當我通過sort方法運行測試時,List完全沒有排序。 – Jammerz858 2012-03-21 13:08:32

+0

@ user1243505:這是因爲這 - 也是馬克的回答 - 不會就地排序。他們返回一個* new *對象,其中包含按排序順序排列的原始列表的內容。 – 2012-03-21 13:14:14

相關問題