.NET Framework System.Array.Sort 演示

本文内容

  • 自定义类

  • Array.Sort
  • 参考资料

System.Array.Sort 有很多对集合的操作,比如排序,查找,克隆等等,你可以利用这个类加深对 IComparer、IComparable、ICloneable 以及泛型委托、匿名方法、Lambda 表达式的理解。

下载 Demo

自定义类



自定义后面用到的 Person 类和 PersonComparer 类。

自定义 Person 类,该类有两个属性:last name 和 first name,重构了 ToString 方法。Person 类还继承 IComparableICloneable 接口,实现了 CompareTo 和 Clone 方法。CompareTo 方法在后面的集合排序时会用到,它通常是默认的排序。如下所示:

public class Person : IComparable, ICloneable
{

    public Person()

    {

 

    }

 

    public Person(string firstname, string lastname)

    {

        this.FirstName = firstname;

        this.LastName = lastname;

    }

 

    public string FirstName { get; set; }

 

    public string LastName { get; set; }

 

    public override string ToString()

    {

        return string.Format("{0} {1}", FirstName, LastName);

    }

 

    public int CompareTo(object obj)

    {

        Person other = obj as Person;

        return this.LastName.CompareTo(other.LastName);

    }

 

    public object Clone()

    {

        return new Person(FirstName, LastName);

    }

}

自定义 PersonComparer 类,该类内定义了比较类型,可以选择按 last name 比较,还是 first name。PersonComparer 类同时继承 IComparer 接口的非泛型形式和泛型形式,实现了它们相应的 Compare 方法,该方法在后面的集合排序中会用到。如下所示:

public class PersonComparer : IComparer, IComparer<Person>
{

    public enum PersonCompareType

    {

        FirstName,

        LastName

    }

 

    private PersonCompareType compareType;

 

    public PersonComparer(PersonCompareType compareType)

    {

        this.compareType = compareType;

    }

 

    public int Compare(object x, object y)

    {

        Person p1 = x as Person;

        Person p2 = y as Person;

        switch (compareType)

        {

            case PersonCompareType.FirstName:

                return p1.FirstName.CompareTo(p2.FirstName);

            case PersonCompareType.LastName:

                return p1.LastName.CompareTo(p2.LastName);

            default:

                throw new ArgumentException("unexpected compare type");

        }

    }

    public int Compare(Person x, Person y)

    {

        Person p1 = x;

        Person p2 = y;

        switch (compareType)

        {

            case PersonCompareType.FirstName:

                return p1.FirstName.CompareTo(p2.FirstName);

            case PersonCompareType.LastName:

                return p1.LastName.CompareTo(p2.LastName);

            default:

                throw new ArgumentException("unexpected compare type");

        }

    }

}

Array.Sort


Array.Sort 有 17 个“重载”,如下所示:

Sort(Array)      
Sort(Array, Array)      

Sort(Array, IComparer)      

Sort(Array, Array, IComparer)      

Sort(Array, Int32, Int32)      

Sort(Array, Array, Int32, Int32)       

Sort(Array, Int32, Int32, IComparer)      

Sort(Array, Array, Int32, Int32, IComparer)         

Sort<T>(T[])       

Sort<T>(T[], IComparer<T>)      

Sort<T>(T[], Comparison<T>)      

Sort<T>(T[], Int32, Int32)       

Sort<T>(T[], Int32, Int32, IComparer<T>)      

Sort<TKey, TValue>(TKey[], TValue[])        

Sort<TKey, TValue>(TKey[], TValue[], IComparer<TKey>)        

Sort<TKey, TValue>(TKey[], TValue[], Int32, Int32)        

Sort<TKey, TValue>(TKey[], TValue[], Int32, Int32, IComparer<TKey>)

从它们的参数,你可以先想象一下:

  • 这些方法可以分成非泛型形式和泛型形式,也就是每个非泛型形式基本都会对应一个泛型形式;

  • 如果我们要对一个集合排序,肯定是要比较的,并且默认是升序;
  • 如果集合是字符串,那很好办,几乎不需要做什么;
  • 可如果集合是对象,那我们就必须指定两个对象之间如何比较以及比较什么;
  • 如果有两个集合,一个集合是当键,另一个集合是当值,用键为值排序,这当然也是可以的,比如 Sort<TKey, TValue>
  • 针对不同的情况,可以指定不同的比较方法,比如,参数中带 ICompare 的。

如果集合仅仅是字符串数组,那很好办,如下代码所示,按升序排序:

string[] names = { "Emerson Fittipaldi", "Niki Lauda", "Ayrton Senna", "Michael Schumacher" };
Array.Sort(names);

但外国人的姓在后面,要是按我们的规矩如何按姓排序?字符串数组就不行了,此时就需要自定义的 Person 类,假设有如下 Person 数组:

Person[] persons = {
    new Person("Emerson", "Fittipaldi"),

    new Person("Niki", "Lauda"),

    new Person("Ayrton", "Senna"),

    new Person("Michael", "Schumacher")

};

按姓的升序排序,采用 Sort(Array) 这个方法,如下代码所示:

Array.Sort(persons);

因为前面定义的 Person 类是继承了 IComparer 接口,并实现了 CompareTo 方法,里面规定了按姓 last name 比较,所以 Array.Sort 方法就知道如何排序了。

如果有时需要按 first name 排序,有时需要用 last name,该怎么办?这是就需要自定义的类 PersonComparer。采用 Sort(Array, IComparer) 这个方法,代码如下所示:

Array.Sort(persons, new PersonComparer(PersonComparer.PersonCompareType.FirstName));
 

Console.WriteLine("Sort By First Name:");

foreach (Person p in persons)

{

    Console.WriteLine("     " + p);

}

 

Array.Sort(persons, new PersonComparer(PersonComparer.PersonCompareType.LastName));

 

Console.WriteLine("Sort By Last Name:");

foreach (Person p in persons)

{

    Console.WriteLine("     " + p);

}

结果:

Sort By First Name:
     Ayrton Senna

     Emerson Fittipaldi

     Michael Schumacher

     Niki Lauda

Sort By Last Name:

     Emerson Fittipaldi

     Niki Lauda

     Michael Schumacher

     Ayrton Senna

如果我们事先没定义 PersonComparer 类,也没问题,可以采用 Sort<T>(T[], Comparison<T>) 这个方法,参数 Comparison<T> 是泛型委托,这意味着我们可以用匿名方法或 Lambda 表达式来规定 Person 如何比较以及比较什么,代码如下所示:

Array.Sort(persons,
    delegate(Person p1, Person p2)

    {

        return p1.FirstName.CompareTo(p2.FirstName);

    });

 

Array.Sort(persons,

    delegate(Person p1, Person p2)

    {

        return p1.LastName.CompareTo(p2.LastName);

    });

Array.Sort(persons, (p1, p2) => p1.FirstName.CompareTo(p2.FirstName));
 

Array.Sort(persons, (p1, p2) => p1.LastName.CompareTo(p2.LastName));

如果用两个集合呢?一个集合用当键,另一个集合当值,用键为值排序,如下代码所示:

Person[] personKeys = {
    new Person("Emerson", "Fittipaldi"),

    new Person("Niki", "Lauda"),

    new Person("Ayrton", "Senna"),

    new Person("Michael", "Schumacher")

};

Person[] personValues = {

    new Person("Emerson", "Fittipaldi"),

    new Person("Niki", "Lauda"),

    new Person("Ayrton", "Senna"),

    new Person("Michael", "Schumacher")

};

 

Array.Sort<Person, Person>(personKeys, personValues);

Array.Sort<Person, Person>(personKeys, personValues, new PersonComparer(PersonComparer.PersonCompareType.FirstName));

Sort 两个参数的泛型方法,personValues 会按 personKeys 的 LastName 排序;而 Sort 三个参数的泛型方法,指定了 personKeys 按 FirstName 排序。

知道 Array.Sort 的用法,其他方法,像检索方法,BinarySearch、Find*** 开头,以及 indexOf 相关,就很好理解了。

参考资料


下载 Demo

时间: 2024-11-11 02:02:37

.NET Framework System.Array.Sort 演示的相关文章

C# 字典排序Array.Sort

Array.Sort可以实现便捷的字典排序,但如果完全相信他,那么就容易产生些异常!太顺利了,往往是前面有坑等你. 比如:微信接口,好多地方需要签名认证,签名的时候需要用的字典排序,如果只用Array.Sort()会出现签名异常的情况,而且是偶尔出现. 问题就在于他的排序默认没有区分大小写,这跟微信的签名将不匹配,所以还是需要自己实现比较的方法 public class DictionarySort : System.Collections.IComparer { public int Comp

C#:System.Array简单使用

1.C# 中的数组 1.1 定义数组: 1.1.1 定义不初始化:数据类型[] 数组名称= new 数据类型[元素个数];    1.1.2 定义并初始化:数据类型[] 数组名称= new 数据类型[]{array1,array2}; 1.2 System.Array 类    C#中提供了一个现成的名为System.Array的类,可以通过这个类提供的属性和方法对数组执行大多数操作. 1.2.1 System.Array 对象创建:Array类是一个抽象类,不能使用如下方式创建        

Method not found: &#39;!!0[] System.Array.Empty()&#39;.

错误原因:程序里面没有可调用的方法(程序使用的是 .NET Framework 4.6,但是你自己的系统里面使用的不是 4.6版本) 解决方法:1.安装window sp1  ,下载地址是:https://www.microsoft.com/zh-cn/download/details.aspx?id=5842 2.安装.NET Framework 4.6  ,下载地址是 :https://www.microsoft.com/zh-cn/download/details.aspx?id=4998

C#中Array.Sort() 快速排序-源码分析

快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序.它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod). 该方法的基本思想是: 1.先从数列中取出一个数作为基准数. 2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边. 3.再对左右区间重复第二步,直到各区间只有一个数. 之前提到过,Array的Sort()方法采用的是快速排序方法,通过使用.NET Reflector对程序集mscorlib进行解析,分析源码.

ToUpperInvariant and Array.Sort

string[] words = { "Tuesday", "Sal?", "Вторник", "Mardi", "Τρ?τη", "Martes", "??? ?????", "????????", "?????????" }; StreamWriter sw = new StreamWriter(@".\outp

Array.Sort 谷歌内核 数组大小超过10 排序字段都一致 返回的数组非原数组

1.如果数据大小小于等于10 都正常 2.数据大小大于10 3.js中Array.sort的实现原理 定义:sort() 方法用于对数组的元素进行排序. api语法:arrayObject.sort(sortby):参数sortby可选,用于规定排序规则,必须是函数. 具体是如何实现的? V8 引擎 sort 函数只给出了两种排序分别是: InsertionSort 和 QuickSort,数组长度小于等于 10 的用插入排序 InsertionSort,比10大的数组则使用快速排序 Quick

Array.sort详解(jdk6)

java.util.Arrays提供了对数组int[] long[] byte[] char[] short[] double[] float[] Object[]的排序算法Arrays.sort(T[]),以及更高级的Arrays.sort(T[], Comparator<? super T> c); 先看对int\long\byte\char\short的排序算法sort1(byte x[], int off, int len) 1)排序长度len<7时,直接采用插入排序,是因为虽然

javascript学习笔记之array.sort

arrayName.sort()方法: 功能是实现排序(按ascii编码或按数字大小),可无参或有参使用,无参时默认升序排列.有参时可实现升序或降序排列,参数必须是具有返回值的方法,当方法表达式大于0时将交换两数的顺序.即 arrayName.sort(表达式 { if(表达式>0) 交换顺序; else if(表达式<0) 不执行操作; else //表达式=0 根据浏览器支持选择具体操作; }); 其中表达式(==方法)将会决定排序原则,具体地实例是 arrayName.sort(func

Array.sort排序

Sorting an Array 1. 数字排序  int[] intArray = new int[] { 4, 1, 3, -23 }; Arrays.sort(intArray);     输出: [-23, 1, 3, 4] 2. 字符串排序,先大写后小写 String[] strArray = new String[] { "z", "a", "C" }; Arrays.sort(strArray); 输出: [C, a, z] 3.