LINQ Enumerable


System.Linq.Enumerable類,提供了數十種稱為擴展方法的共享方法,幫助您操作所有實現IEnumerable(of T)接口的類中的數據。由於Enumerable類的擴展方法可以處理許多其他類如(包括Array和List),因此不僅可以使用Enumerable類的方法來創建LINQ查詢,還可以用它來操作數組和其他數據結構的行為。

查看Enumerable類擴展方法的文檔,你會發現每個成員都為Shared。因此可以通過兩種方案來調用方法。

第一種方案:按照聲明類型的方法來調用,即傳入擴展類的實例

 Dim itemcount = Enumerable.Count(query, Function(prod) prod.Equals("Chang"))

第二種方案:想操作集合本身的實例方法一樣,調用擴展方法,不必提供第一個參數

 Dim itemCount1 = queryAgain.Count(Function(qS) qS.Equals("Chang"))

從經過排序的數據中取得前10項,擴展方法Take:從序列的開頭返回指定數量的連續元素。

    Dim query = _
        db.Products.Where(Function(product) product.CategoryId = 1) _
                   .OrderBy(Function(product) product.ProductName) _
                   .Select(Function(product) product.ProductName) _
                   .Take(10)

創建序列

Enumerable類提供了多個shared方法,但他們不是擴展方法,我們先從這些簡單的方法開始。

Enumerable.Range

Enumerable.Range方法創建一個新的整數有序列表。可指定列表的起始值和項目數。此方法將返回一個IEnumerable(of Integer)序列。下面代碼,使用Range方法填充列表,然后使用一個簡單的lambda表達式調用Enumerable.orderby方法,按隨機順序排列序列。

        Dim rad As New System.Random
        Dim items = Enumerable.Range(1, 10)
        Dim randomList = items.OrderBy(Function() rad.Next())

多次運行代碼時,每次返回不同的結果。

Enumberable.Reverse

Enumberable.Reverse方法以相反順序返回輸入序列。

        Dim items = Enumerable.Range(1, 10)
        Dim reversed = items.Reverse()

Enumerable.Repeat

Enumerable.Repeat方法創建包括指定值,且按指定次數重復的一個列表。

        Dim repeated = Enumerable.Repeat("Hello", 6)

執行代碼后,repeated變量為

Hello, Hello, Hello, Hello, Hello, Hello
 

選擇序列

Enumerable.select

Enumerable.select方法將每個元素投影成新的格式。

 Dim db As New SimpleDataContext
 Dim results = db.Customers.Where(Function(customer) customer.Country = "USA") _
                 .Select(Function(customer, index) _
                 String.Format("{0}.{1}", index + 1, customer.ContactName))

Enumerable.selectMany

Enumerable.selectMany方法獲取一個項目集合,其中的每個項目可能又是一個項目集合,然后將兩維輸入縮成一維輸出序列。例如,如果需要獲取種類列表,每個種類又包括多個產品,並最終得到具有對應種類信息的產品列表,此方法會非常有用。

Dim db As New SimpleDataContext
Dim categories = db.Categories _
                   .Where(Function(category) category.Products.Count < 7)

Dim reuslts = categories.SelectMany( _
    Function(category, index) category.Products.Select( _
        Function(product) String.Format("{0}.Category {1}:{2}", _
                          index, product.CategoryId, product.ProductName)))

在此示例中,傳到selectMany方法的lambda表達式接受對特定種類的引用(依次處理每個種類)。selectMany方法的這一特定重載將種類的索引以及種類一起傳遞給 lambda 表達式。有了種類及其索引后,lambda 表達式將針對種類的 Products 屬性調用 Select 方法,允許它處理種類中的每個產品。此示例返回包含以下字符串列表的一個序列。調用 SelectMany 將原始種類/產品層次結構平鋪成單個值列表。

檢索單個元素

你常常會需要檢索和處理序列中的單個元素。Enumerable類提供了多種方法來將序列內容篩選成單個元素。

Enumerable.First、Enumerable.Last

Enumerable.first和Enumerable.last方法分別返回序列中的第一個和最后一個元素。

Enumerable.Single

給定指定單個元素的函數或者Lambda表達式后,Enumerable.Single方法將返回一個元素。

Enumerable.ElementAt

Enumerable.ElementAt方法將返回位於序列中特定索引位置的一個元素。

如果序列中並不存在請求的元素(對於Single方法而言,如果限制條件導致出現零個元素或多個元素),上述每種方法都會拋出異常。它們還允許指定一個lambda表達式或函數來限制輸入數據。在任何情況下,結果序列必須包含一個元素。

Enumerable 類還提供類似方法,它在條件允許時返回單個元素,否則返回序列類型的默認成員。這些方法是 Enumerable.FirstOrDefault、Enumerable.LastOrDefault、Enumerable.SingleOrDefault 和 Enumerable.ElementAtOrDefault。

篩選序列

Enumerable.where、Enumerable.Distinct或者Enumerable.OfType方法篩選現有序列的內容,即可返回輸出序列中原始數據的子集。

Enumerable.OfType

Enumerable.OfType方法基於指定類型篩選輸入序列。假設希望僅針對窗體上特定類型的控件執行操作。通過使用OfType方法,可以限制窗體公開的控件集合並僅遍歷相關的控件子集。

 Dim items As New List(Of Object)
 items.Add("January")
 items.Add(0)
 items.Add("Monday")
 items.Add(3)
 items.Add(5)
 items.Add("September")

 Dim numbers = items.OfType(Of Integer)()
 Dim strings = items.OfType(Of String)()

代碼運行后的,兩個輸出列表,包含以下數據:

0, 3, 5
January, Monday, September

Enumerable.Where

Enumerable.where方法允許指定篩選輸入序列的條件。第二個重載版本可訪問集合中每個項目的索引,以便根據索引執行篩選。

Dim files As IEnumerable(Of FileInfo) = _
    New DirectoryInfo("C:\Windows").GetFiles()
Dim fileResults = _
    files.Where(Function(file) file.Length < 100) _
    .Select(Function(file) String.Format("{0}  ({1})", file.Name,file.Length))

上面代碼中,New DirectoryInfo("C:\Windows").GetFiles()返回的是,System.IO.FileInfo 類型數組。由於數組實現了IEnumerable接口,因此可使用where方法篩選數組內容。

fileResults = _
   files.Where(Function(file, index) ((file.Length < 100) And (index < 20))) _
   .Select(Function(file) String.Format("{0} ({1})", file.Name, file.Length))

Enumerable.Distinct

Enmerable.Distinct方法可篩選列表,使輸出序列僅包含輸入列表中單獨存在的項目。對應簡單的值(字符串、數字等),此過程非常簡單。

對於復雜對象列表,運行時引擎如何才能通過比較確定兩個對象是否重復?無法簡單地比較實例變量,這一點與在實際操作中僅比較對象的地址不同。對於復雜對象,必須提供一個比較器,即實現IEqualityComparer(Of T)執行比較。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM