C#自定義類型數組排序


在數組或者集合中對自定義類型進行排序分為兩種方法。

1.如果這個自定義類型是自己定義編寫的,那么我可以使它繼承ICompareable<T>接口,實現其中的CompareTo(Object)方法。然后直接Array.Sort(排序對象數組)對其進行排序。

 1     class Book: IComparable<Book>
 2     {
 3         //defined name and number for book
 4         public string BookName { get; set; }
 5         public string BookNo { get; set; }
 6         // implement the CompareTo method
 7         public int CompareTo(Book other)
 8         {
 9             if (other == null) throw new ArgumentNullException("other");
10             // compare to BookNo
11             return this.BookNo.CompareTo(other.BookNo);
12         }
13     }

我自定義了一個Book類型。有BookName和BookNo屬性。我使它繼承了ICompareable<Book>接口。並且實現了CompareTo(Book)方法。這樣,我就可以直接用Array.Sort()對

這個數組按BookNo進行排序。

 1        static void test2() 
 2         {
 3             Book[] bookArray = {
 4                                    new Book{BookName = "AAA",BookNo = "0001"},
 5                                    new Book{BookName = "DDD",BookNo = "0004"},
 6                                    new Book{BookName = "CCC",BookNo = "0003"},
 7                                    new Book{BookName = "BBB",BookNo = "0002"},
 8                                };
 9             Array.Sort(bookArray);
10             foreach (Book item in bookArray) 
11             {
12                 Console.WriteLine("BookName = \"{0}\"; BookNo = \"{1}\".",item.BookName,item.BookNo);
13             }
14 
15         }

輸出結果:

BookName = "AAA"; BookNo = "0001".
BookName = "BBB"; BookNo = "0002".
BookName = "CCC"; BookNo = "0003".
BookName = "DDD"; BookNo = "0004".

2.如果這個自定義類型不是自己編寫的,是別人已經編寫好的的一個類型,我不能修改這個類型。或者我想按照BookName排序,但是還不能修改現有的Book類該怎么辦?

   我們可以對這個類型進行包裝。

1     class Person
2     {
3         public string PersonName { get; set; }
4         public string PersonAge {get;set;}
5     }

Person這個類型沒有繼承ICompare接口。這個類不能修改,但是我還要對PersonAge進行排序。

我自己創建一個PersonCompare類,它實現了ICompare<T>接口,我把排序規則寫在這個類中。

1     class PersonCompare : IComparer<Person> 
2     {
3         public int Compare(Person x, Person y)
4         {
5             if (x == null || y == null) throw new ArgumentNullException("argument error.");
6             return x.PersonAge.CompareTo(y.PersonAge); //sort rule
7         }
8     }

測試:

 1        static void test3() 
 2         {
 3             Person[] personArray = {
 4                                        new Person{PersonName = "AAA",PersonAge = "23"},
 5                                        new Person{PersonName = "EEE",PersonAge = "25"},
 6                                        new Person{PersonName = "CCC",PersonAge = "24"},
 7                                        new Person{PersonName = "FFF",PersonAge = "26"},
 8                                    };
 9             Array.Sort(personArray,new PersonCompare());//second parameter is sort rule
10             foreach(Person item in personArray)
11             {
12                 Console.WriteLine("PersonName = \"{0}\"; PersonAge = \"{1}\".", item.PersonName, item.PersonAge);
13             }
14         }

輸出結果:

PersonName = "AAA"; PersonAge = "23".
PersonName = "CCC"; PersonAge = "24".
PersonName = "EEE"; PersonAge = "25".
PersonName = "FFF"; PersonAge = "26".

擴展:

如果我想對指定的屬性進行排序怎么辦?比如有的同事需要用PersonAge進行排序,有的需要使用PersonName進行排序。這種需求很常見。我們修改下PersonCompare方法。

為了使代碼更加的規范。我建議以Person的屬性為基礎創建一個枚舉。這個enum控制着我要按照那個屬性進行排序。

1    enum PersonType
2     {
3         PersonName,
4         PersonAge
5     }

我們需要PersonType作為參數傳遞給PersonCompare。以實現根據需求來定制排序規則。

   class PersonCompare : IComparer<Person> 
    {
        private PersonType useType;
        public PersonCompare(PersonType pt)
        {
            this.useType = pt;
        }
        public int Compare(Person x, Person y)
        {
            if (x == null || y == null) throw new ArgumentNullException("argument error.");
            //return x.PersonAge.CompareTo(y.PersonAge);
            switch (useType){
                case PersonType.PersonAge:
                    return x.PersonAge.CompareTo(y.PersonAge);
                case PersonType.PersonName:
                    return x.PersonName.CompareTo(y.PersonName);
                default :
                    throw new ArgumentNullException("Doesn't contain this type.");
            }
        }
    }

測試:

 1        static void test3() 
 2         {
 3             Person[] personArray = {
 4                                        new Person{PersonName = "AAA",PersonAge = "23"},
 5                                        new Person{PersonName = "EEE",PersonAge = "25"},
 6                                        new Person{PersonName = "CCC",PersonAge = "23"},
 7                                        new Person{PersonName = "FFF",PersonAge = "26"},
 8                                    };
 9             Array.Sort(personArray,new PersonCompare(PersonType.PersonAge));// sort by age
10             foreach(Person item in personArray)
11             {
12                 Console.WriteLine("PersonName = \"{0}\"; PersonAge = \"{1}\".", item.PersonName, item.PersonAge);
13             }
14             Console.WriteLine("---------------------------------------------------");
15             Array.Sort(personArray, new PersonCompare(PersonType.PersonName)); // sort by name
16             foreach (Person item in personArray)
17             {
18                 Console.WriteLine("PersonName = \"{0}\"; PersonAge = \"{1}\".", item.PersonName, item.PersonAge);
19             }
20         }

輸出結果:

PersonName = "CCC"; PersonAge = "23".
PersonName = "AAA"; PersonAge = "23".
PersonName = "EEE"; PersonAge = "25".
PersonName = "FFF"; PersonAge = "26".
---------------------------------------------------
PersonName = "AAA"; PersonAge = "23".
PersonName = "CCC"; PersonAge = "23".
PersonName = "EEE"; PersonAge = "25".
PersonName = "FFF"; PersonAge = "26".

總結:

     其實數組和集合的排序一樣。如果對自己定義的類型數組或者集合排序就用IComareable<T>。如果要對已有的類型數組或者集合排序就用IComare<T>.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM