zoukankan      html  css  js  c++  java
  • 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>.

  • 相关阅读:
    Javascript Promise对象学习
    JavaScript 判断一个对象的数据类型。
    Angular SEO方案
    【GOF23设计模式】迭代器模式
    【GOF23设计模式】责任链模式
    【GOF23设计模式】享元模式
    【GOF23设计模式】外观模式
    【GOF23设计模式】装饰模式
    【GOF23设计模式】组合模式
    【GOF23设计模式】桥接模式
  • 原文地址:https://www.cnblogs.com/forbetter223/p/10930887.html
Copyright © 2011-2022 走看看