程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 排序Ordering

排序Ordering

編輯:關於.NET

分組Grouping

主要方法:

GroupBy: 將一個序列分組插入一個子序列, 對應SQL語法是GROUP BY

主要參數:

輸入序列: IEnumerable

主鍵選擇器: TSource => TKey

元素選擇器(可選): TSource => TElement

比較器(可選):IEqualityComperar

返回類型是IEnumerable>

簡要介紹

GroupBy將一個扁平的輸入序列轉換成一組序列, 例如,以下示例通過文件擴展名將c:\temp下面的文件分組:

   1: string[] files = Directory.GetFiles(“c:\\temp”);
   2:  
   3: IEnumerable<string,string>> query =
   4:  
   5: files.GroupBy(file => Path.GetExtension(file));

 

或者,你可以使用隱式類型減少代碼輸入:

   1: var query = files.GroupBy(file => Path.GetExtension(file));

 

枚舉返回結果:

   1: foreach (IGrouping<string,string>grouping in query)
   2:  
   3: {
   4:  
   5: Console.WriteLine(“Extension: “ + grouping.Key);
   6:  
   7: foreach (string filename in grouping)
   8:  
   9: Console.WriteLine (” - “ + filename);
  10:  
  11: }

 

Enumerable.GroupBy將輸入元素讀入臨時的目錄字典,所有擁有相同key的元素都會被歸入相同的二級目錄. 默認情況下, 每一個grouping的元素都是未轉換的輸入元素, 除非你提供了一個elementSelector參數. 以下查詢將每一個元素都轉換為大寫:

   1: files.GroupBy (file =>
   2:  
   3: ath.GetExtension (file), file => file.ToUpper());

 

elementSelector和keySelector是獨立的,因此此查詢將會得到與上面一樣的分組結果.

另外,所有的子序列並不會根據字母排序,它只做分組, 而沒有做任何排序相關的工作, 只是簡單保存了原有序列排列的順序. 如果你要排序, 必須要顯式調用OrderBy操作符:

   1: string[] files = Directory.GetFiles(“c:\\temp”);
   2:  
   3: files.GroupBy (file => Path.GetExtension(file), file => file.ToUpper())
   4:  
   5: .OrderBy (grouping => grouping.Key);

 

如果使用復合查詢語法:

   1: from file in files
   2:  
   3: group file.ToUpper() by Path.GetExtension(file);

 

與select類似, group結束一個查詢語句,除非你使用”延續查詢”語句:

   1: from file in files
   2:  
   3: group file.ToUpper() by Path.GetExtension(file)
   4:  
   5: into grouping
   6:  
   7: orderby grouping.Key
   8:  
   9: select grouping;

 

延續查詢通常在group by查詢中是很有用的,以下示例顯示那些文件總數小於5的分組目錄:

   1: from file in files
   2:  
   3: group file. ToUpper()by Path.GetExtension (file)
   4:  
   5: into grouping
   6:  
   7: where grouping.Count() < 5
   8:  
   9: select grouping;

 

有些時候你可能只需要得到一個組的聚合結果,因此你可以丟棄子序列:

   1: string[] votes = {“Bush”,“Gore”,“Gore”,“Bush”,“Bush” };
   2:  
   3: IEnumerable<string> query = from vote in votes
   4:  
   5: group vote by vote into g
   6:  
   7: orderby g.Count() descending
   8:  
   9: select g.Key;
  10:  
  11: string winner = query.First(); // Bush

 

LINQ to SQL當中的GroupBy

Grouping在解釋性查詢中的工作方式與上述是一樣的. 當然, 如果你在LINQ to SQL實體當中有關聯屬性, 你會發現需要使用group的時候比在標准SQL當中要少很多.例如, 要找到那些采購訂單不少於兩個的客戶, 我們並不需要group, 以下示例就可以了:

   1: from c in dataContext.Customers
   2:  
   3: where c.Purchases.Count >= 2
   4:  
   5: select c.Name + ” has made “ + c.Purchases.Count
   6:  
   7: + ” purchases”;

 

另外一個你可能需要分組的例子是計算年度收入:

   1: from p in dataContext.Purchases
   2:  
   3: group p.Price by p.Date.Year into salesByYear
   4:  
   5: select new {
   6:  
   7: Year = salesByYear.Key,
   8:  
   9: TotalValue = salesByYear.Sum()
  10:  
  11: };

 

多主鍵分組

我們可以使用一個匿名類型根據一個符合主鍵進行分組

   1: from n in names
   2:  
   3: group n by new { FirstLetter = n[0], Length = n.Length };

 

自定義Comparer

對於本地查詢,你可以傳遞一個自定義的comparer到GroupBy中改變默認的主鍵比較算法.雖然這種需求是極少的,因為通常改變keySelector就足夠了.以下示例創建不區分大小寫的分組:

   1: group name by name.ToUpper()

 

待續!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved