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>.

原文地址:https://www.cnblogs.com/forbetter223/p/10930887.html