LINQ Enumerable

System.Linq.Enumerable類,提供了數十種稱爲擴展方法的共享方法,幫助您操做全部實現IEnumerable(of T)接口的類中的數據。因爲Enumerable類的擴展方法能夠處理許多其餘類如(包括Array和List),所以不只可使用Enumerable類的方法來建立LINQ查詢,還能夠用它來操做數組和其餘數據結構的行爲。數組

查看Enumerable類擴展方法的文檔,你會發現每一個成員都爲Shared。所以能夠經過兩種方案來調用方法。數據結構

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

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

第二種方案:想操做集合自己的實例方法同樣,調用擴展方法,沒必要提供第一個參數spa

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

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

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

建立序列

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

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)執行比較。

相關文章
相關標籤/搜索