Linq查詢操做之排序操做

  在Linq中排序操做能夠按照一個或多個關鍵字對序列進行排序。其中第一個排序關鍵字爲主要關鍵字,第二個排序關鍵字爲次要關鍵字。Linq排序操做共包含如下5個基本的操做。web

一、OrderBy操做,根據排序關鍵字對序列進行升序排序函數

二、OrderByDescending操做,根據排序關鍵字對序列進行降序排序測試

三、ThenBy操做,對次要關鍵字進行升序排序this

四、ThenByDescending操做,對次要關鍵字進行降序排序spa

五、Reverse操做,將序列中的元素進行反轉3d

  那麼下面咱們就逐一來分析一下每一個排序操做。code

OrderBy操做blog

  OrderBy操做是按照主關鍵字對序列進行升序排序的操做。Enumerable類的OrderBy()原型以下:排序

1public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
    return new OrderedEnumerable<TSource, TKey>(source, keySelector, null, false);
}

 
2public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
{
    return new OrderedEnumerable<TSource, TKey>(source, keySelector, comparer, false);
}

 

 


 

其中source表示數據源,keySelector表示獲取排序的關鍵字的函數,comparer參數表示排序時的比較函數。TSource表示數據源的類型,TKey表示排序關鍵字的類型。下面咱們用兩種方式來比較排序,第一種按照前面講的查詢表達式來排序,第二種用如今的排序操做來排序,其實結果都是同樣的。接口

private void OrderByQuery()
        {
            int[] ints = new int[] { 1, 3, 5, 4, 7, 6, 8 };

            //使用查詢表達式來排序

            Response.Write("--------------使用查詢表達式來排序---------</br>");
            var values = from v in ints

                         orderby v

                         select v;

            foreach (var item in values)
            {

                Response.Write(item+"</br>");
            }
             //使用排序操做來排序

            Response.Write("--------------使用排序操做來排序---------</br>");

            var result = ints.OrderBy(x => x);

            foreach (var re in result)
            {

                Response.Write(re + "</br>");
            }

        }

看看運行結果:

咱們看到和咱們預想的是同樣的。那麼你們可能有些疑問,爲何OrderBy是升序排序呢?

咱們來從源碼解析一下:

咱們看到OrderBy裏面最終調用了一個函數OrderedEnumerable,那麼咱們再來看看這個OrderedEnumerable函數:

看到這個函數有一個參數descending,咱們OrderBy方法給這個參數傳了false,那麼就表示非降序排序,就是升序排序。可想而知,OrderByDescending操做,給這個參數傳值應該是true。

第二個原型裏面有個comparer參數,那麼咱們來看看怎麼用:既然是IComparer接口類型的參數,那麼咱們就定義一個實現了Icomparer接口的類型:

 1 private void OrderByQuery()
 2         {
 3             int[] ints = new int[] { 1, 3, 5, 4, 7, 6, 8 };
 4 
 5 
 6             var result = ints.OrderBy(x => x,new CompareIntegers());
 7 
 8             foreach (var re in result)
 9             {
10 
11                 Response.Write(re + "</br>");
12             }
13 
14         }
15 
16         public class CompareIntegers : IComparer<int>
17         {
18             public int Compare(int i1, int i2)
19             {
20                 return -1*(i1 - i2);
21             }
22         }

咱們看到,咱們定義的CompareIntegers類的比較參數是,該元素取反,因此排序結果應該就成了降序排序了。咱們看看測試結果:

嗯和咱們預想的同樣,這個comparer函數就是咱們自定義的比較方式。

OrderByDescending操做

  OrderByDescending和咱們上面的OrderBy操做類似,最終都是調用OrderedEnumerable只是傳入的descending參數的值不一樣。看看OrderByDescending的原型:

    public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector);

    public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer);

也有兩個原型,跟OrderBy的原型如出一轍,只是最終調用OrderedEnumerable方法的傳入參數不一樣。

咱們看到這個傳入的是true,表示降序排列。因此我我的以爲這兩個操做能夠合併,而後多一個參數而已。

一樣寫個例子測試一下:

 1  private void OrderByDescendingQuery()
 2         {
 3             int[] ints = new int[] { 1, 3, 5, 4, 7, 6, 8 };
 4 
 5             //使用查詢表達式來排序
 6 
 7             Response.Write("--------------使用查詢表達式來排序---------</br>");
 8             var values = from v in ints
 9 
10                          orderby v descending
11 
12                          select v;
13 
14             foreach (var item in values)
15             {
16 
17                 Response.Write(item+"</br>");
18             }
19          //使用排序操做來排序
20 
21             Response.Write("--------------使用排序操做來排序---------</br>");
22 
23             var result = ints.OrderByDescending(x => x);
24 
25             foreach (var re in result)
26             {
27 
28                 Response.Write(re + "</br>");
29             }
30 
31         }

看看測試結果:

嗯結果和預想的同樣。

ThenBy操做

  上面兩個排序都是按照主關鍵字來排序的,下面呢咱們就看看什麼是按照次要關鍵字排序。ThenBy 和OrderBy同樣是按照升序排序的。來看看原型:

    public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey>(this IOrderedEnumerable<TSource> source, Func<TSource, TKey> keySelector);
    public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey>(this IOrderedEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer);

原型和OrderBy同樣。可是ThenBy必需要和OrderBy配合使用。就是 必需要先有OrderBy排序,而後再用ThenBy排序。不可以直接用ThenBy排序。
一樣咱們寫個例子一看便知。這個例子呢咱們每一個序列的每一個元素至少要有兩個字段,一個作主關鍵字,一個作次要關鍵字。咱們仍是用前面將的UserBaseInfo來建立例子,用ID作主關鍵字,username作次要關鍵字。

 1 private void ThenByQuery()
 2         {
 3             IList<UserBaseInfo> users = new List<UserBaseInfo>();
 4 
 5             for (int i = 1; i < 10; i++)
 6             {
 7                 users.Add(new UserBaseInfo(i, "user0" + i.ToString(), "user0" + i.ToString() + "@web.com"));
 8             }
 9 
10             var values = users.OrderBy(u => u.ID).ThenBy(x => x.UserName);
11 
12             foreach (var u in values)
13             {
14                 Response.Write("ID:" + u.ID + "</br>" + "username:" + u.UserName + "</br>");
15             }
16 
17 
18         }

看看結果:

ThenByDescending操做

  這個是ThenBy的降序排序方式,和前面的用法實質是同樣的,我就不詳細講解了,你們能夠本身研究一下。

Reverse操做

  下面咱們就來看看Reverse這個排序。這個排序呢能夠說也不算是排序,由於咱們知道排序無非就是升序,或者降序。這個其實就是將一個序列進行反轉,裏面的值若是原本沒有順序,執行這個操做以後,也不會變得有序,只是序列的元素反轉。

看看reverse的原型:

public static IEnumerable<TSource> Reverse<TSource>(this IEnumerable<TSource> source);

測試樣例:

 1 private void ReverseQuery()
 2         {
 3             IList<UserBaseInfo> users = new List<UserBaseInfo>();
 4 
 5             for (int i = 1; i < 10; i++)
 6             {
 7                 users.Add(new UserBaseInfo(i, "user0" + i.ToString(), "user0" + i.ToString() + "@web.com"));
 8             }
 9 
10             var values = users.Reverse();
11 
12             foreach (var u in values)
13             {
14                 Response.Write("ID:" + u.ID + "</br>" + "username:" + u.UserName + "</br>");
15             }
16 
17 
18         }

運行結果:

看確實是反轉了。

  再看一個原本無序的例子。

 1 private void ReverseQuery()
 2         {
 3             int[] ints = new int[] { 1, 3, 5, 4, 7, 6, 8 };
 4 
 5 
 6             var result = ints.Reverse();
 7 
 8             foreach (var re in result)
 9             {
10 
11                 Response.Write(re + "</br>");
12             }
13 
14         }

運行結果:

能夠看出,只是把序列的元素反轉了,並不會進行升序或者降序排序。

咱們來看看內部實現,內部實現其實很簡單:

就是對序列反向輸出。

相關文章
相關標籤/搜索