LINQ Enumerable 續 II

Enumerable.TakeWhile和Enumerable.SkpWhile

Enumerable.TakeWhile和Enumerable.SkpWhile將經過判斷條件,來獲取和跳過序列。數據庫

TakeWhile方法會在條件爲真時,將按照條件繼續檢索序列,直到條件爲false。當條件爲false時,則馬上中止檢索,並返回此時已經檢索過的序列。express

SkpWhile方法會在條件爲真時,將按照條件繼續檢索序列,直到條件爲false。當條件爲false時,則馬上中止檢索,並返回此時還沒有檢索的序列。dom

        Dim sw As New StringWriter
        Dim rnd As New Random

        Dim cutOff As Integer = rnd.Next(50, 100)
        'create a list of containing a fixed set of random numbers:
        Dim items As New List(Of Integer)
        For i As Integer = 1 To 20
            items.Add(rnd.Next(1, 100))
        Next

        sw.WriteLine("the cutoff value was :{0}", cutOff)
        sw.WriteLine("the full list is :")
        For Each item As Integer In items
            sw.Write("{0},", item)
        Next

        Dim list = items.TakeWhile(Function(item) item < cutOff)
        'show the list :
        sw.WriteLine()
        sw.WriteLine("the result list is (item < cutoff):")
        For Each item As Integer In list
            sw.Write("{0},", item)
        Next

        'can also pass in the index to the lambda expression:
        list = items.TakeWhile(Function(item, index) item > index)
        sw.WriteLine()
        sw.WriteLine("result list is (takewhile item >index):")
        For Each item As Integer In list
            sw.Write("{0},", item)
        Next

        list = items.SkipWhile(Function(item, index) item > index)
        sw.WriteLine()
        sw.WriteLine("the result list is (skipwhile item >index):")
        For Each item As Integer In list
            sw.Write("{0},", item)
        Next

輸出的一次結果爲:函數

the cutoff value was :62
the full list is :
33,40,60,57,27,98,93,53,31,37,62,91,82,19,64,30,6,74,98,58,
the result list is (item < cutoff):
33,40,60,57,27,
result list is (takewhile item >index):
33,40,60,57,27,98,93,53,31,37,62,91,82,19,64,30,
the result list is (skipwhile item >index):
6,74,98,58,ui

計算序列

Enumerable類提供了多種不一樣的序列計算方法。this

Enumerable.Average,Enumerable.Count,Enumerable.Sum,Enumerable.Min,Enumerable.Max

很少說了,看代碼吧~spa

Dim db As New SimpleDataContext
Dim results = db.Products _
              .Where(Function(product) product.CategoryId = 1) _
              .Select(Function(product) product.UnitPrice)

Dim average = results.Average()
Console.WriteLine("average is {0}", average)

Dim decimalResults = db.Products _
                     .Where(Function(product) product.CategoryId = 1)
Dim average1 = decimalResults.Average(Function(product) product.UnitPrice)
Console.WriteLine("average1 is  {0}", average1)

Dim average2 = db.Products _
               .Where(Function(product) product.CategoryId = 1) _
               .Average(Function(product) product.UnitPrice)
Console.WriteLine("average2 is {0}", average2)

Dim count = results.Count()
Console.WriteLine("count is {0}", count)

'calculate filtered count :
Dim filteredCount = db.Products.Where(Function(product) product.CategoryId = 1) _
                     .Count(Function(product) product.ProductName.StartsWith("C"))
Console.WriteLine("filteredCount is {0}", filteredCount)

'retrieve the maximum unit price
Dim max = db.Products.Where(Function(product) product.CategoryId = 1) _
          .Max(Function(product) product.UnitPrice)
Console.WriteLine("the Max is {0}", max)

'retrieve the minimum unit price for products
'whose name starts with C
Dim min = db.Products.Where(Function(product) product.ProductName.StartsWith("C")) _
          .Min(Function(product) product.UnitPrice)
Console.WriteLine("the min is {0}", min)
'calculate sum of units in stock:
Dim total = db.Products.Where(Function(product) product.CategoryId = 1) _
            .Sum(Function(product) product.UnitsInStock)
Console.WriteLine("total is {0}", total)

Enumerable.Aggregate

對序列應該累加器。一個很好用的方法~~·code

Aggregate方法可簡化在值序列上執行計算。此方法的工做原理是對source中的每一個元素調用一次func。每次調用func時,Aggregate都將傳遞序列中的元素和聚合值(聚合值爲func的第一個參數)。將seed參數的值做爲聚合的初始值。用func的結果替換之前的聚合值。Aggregate返回func的最終結果。對象

Dim sw As New StringWriter
Dim its() As Integer = {4, 8, 8, 3, 9, 0, 7, 8, 2}
'count the even numbers in the array,using a seed value of 0
Dim numEven As Integer = _
    its.Aggregate(0, Function(total, number) _
                        If(number Mod 2 = 0, total + 1, total))
sw.WriteLine("Even Number Count:{0}", numEven)

Dim db As New SimpleDataContext
Dim customers = db.Customers _
                .Where(Function(customer) customer.Country = "France") _
                .Select(Function(customer) customer.ContactName)

'note that the seed value is an empty string
Dim customerNames = customers.Aggregate(String.Empty, _
                    Function(current, name) _
                    If(String.IsNullOrEmpty(current), name, current & "," & name))

'you can also write like this:
Dim customerNames1 = customers.Aggregate(Function(current, name) current & "," & name)

sw.WriteLine("France  People ")
sw.WriteLine(customerNames)
sw.WriteLine("Also like this")
sw.WriteLine(customerNames1)
Dim sentence As String _
    = "the quick brown fox jumps over the lazy dog"
'split the string into individual words
Dim words() As String = sentence.Split(" "c)
'reverse the word 
Dim reversed As String = _
    words.Aggregate(Function(current, word) word & " " & current)


sw.WriteLine("At First the string :")
sw.WriteLine(sentence)
sw.WriteLine("after reverse:")
sw.WriteLine(reversed)

執行集合操做

Enumerable提供了執行集合操做的方法,例如並集和交集的計算ip

Enumerable.Concat,Enumerable.Union,Enumerable.Intersect,Enumerable.Except

Enumerable.Concat 鏈接。是將一個序列所有添加到另外一個序列。

Enumerable.Unin 合併。是將一個序列鏈接到另外一序列,並從結果中刪除重複項。

Enumerable.Intersect 相交。返回的序列是兩個輸入序列所共有的所有項目。

Enumerable.Except 與非。返回的序列是屬於第一個序列但不屬於第二個序列所有項目

Dim db As New SimpleDataContext
Dim sw As New StringWriter
'create two sequences:
Dim groupA = db.Customers _
             .Select(Function(customer, index) _
                         customer.Country).Take(5)
Dim groupB = db.Customers _
             .Select(Function(customer, index) customer.Country) _
                         .Skip(30).Take(5)
'show both groups :
sw.WriteLine("group1: ")
ShowEnumerable(groupA, sw)

sw.WriteLine("Group2 :")
ShowEnumerable(groupB, sw)

'return the complete list of countries
Dim groupForConcat = groupA.Concat(groupB)
sw.WriteLine("this is Concat,groupForConcat:")
ShowEnumerable(groupForConcat, sw)

'return a unique list of countries in the two groups :
Dim gourpForUnique = groupA.Union(groupB)
sw.WriteLine("this is Union ,gourpForUnique:")
ShowEnumerable(gourpForUnique, sw)

Dim groupIntersect = groupA.Intersect(groupB)
sw.WriteLine("this is Intersect ,groupIntersect:")
ShowEnumerable(groupIntersect, sw)

sw.WriteLine("this is Except ,groupExcept:")
Dim groupExcept = groupA.Except(groupB)
ShowEnumerable(groupExcept, sw)

輸出的結果:

group1:
Brazil,Mexico,Mexico,UK,Sweden

Group2 :
Brazil,USA,Venezuela,Brazil,Venezuela

this is Concat,groupForConcat:
Brazil,Mexico,Mexico,UK,Sweden,Brazil,USA,Venezuela,Brazil,Venezuela

this is Union ,gourpForUnique:
Brazil,Mexico,UK,Sweden,USA,Venezuela

this is Intersect ,groupIntersect:
Brazil

this is Except ,groupExcept:
Mexico,UK,Sweden

注意,上面的示例使用的都是默認的簡單比較器。若是對複雜對象的序列執行集合操做,能夠調用那些接受自定義比較器的重載版本方法。

Enumerable.Join

假設一些場景你提供了兩個相關序列,你但願根據這兩個序列中的鍵值關聯性將其聯接在一塊兒。此類任務會被認爲是處理關係型數據庫中的某些狀況。

Dim db As New SimpleDataContext
Dim categrories = db.Categories _
                  .Where(Function(category) category.CategoryId = 3)

Dim results = categrories.Join(db.Products, _
                           Function(category) category.CategoryId, _
                           Function(product) product.CategoryId, _
                           Function(category, product) _
                               New With {.CategoryName = category.CategoryName, _
                                        .ProductName = product.ProductName})

Dim sw = New StringWriter
For Each item In results
    sw.WriteLine("{0}----{1}", item.CategoryName, item.ProductName)
Next

Enumerable.GroupBy

Enumerable.GroupBy方法按照鍵值將輸入序列進行分組,這將建立多組項目。輸出序列中的每一個組都包含一個」Header」項目以及提供對分組項目訪問的Items屬性。要調用Enumerable.GroupBy方法,必須至少提供三個函數。第一個提供分組鍵,第二個提供在組中生成的項目,第三個提供標題內容。

Dim db = New SimpleDataContext
Dim groupedProducts = db.Products _
           .Where(Function(product) product.UnitsInStock < 10) _
           .GroupBy(Function(product) product.CategoryId, _
                Function(product) _
                    New With {product.ProductName, product.UnitsInStock}, _
                Function(catId, group) _
                    New With {.CategoryID = catId, .Count = group.Count(), .Items = group})

Dim sw = New StringWriter
For Each grouping In groupedProducts
    sw.WriteLine("Category {0} :{1} items", grouping.CategoryID, grouping.Count)
    For Each item In grouping.Items
        sw.WriteLine("{0} {1} ({2})", vbTab, item.ProductName, item.UnitsInStock)
    Next
Next

輸出結果爲:

Category 2 :3 items     Chef Anton's Gumbo Mix (0)     Northwoods Cranberry Sauce (6)     Louisiana Hot Spiced Okra (4)Category 6 :3 items     Alice Mutton (0)     Thüringer Rostbratwurst (0)     Perth Pasties (0)Category 3 :2 items     Sir Rodney's Scones (3)     Scottish Longbreads (6)Category 4 :2 items     Gorgonzola Telino (0)     Mascarpone Fabioli (9)Category 8 :1 items     Røgede sild (5)Category 7 :1 items     Longlife Tofu (4)

相關文章
相關標籤/搜索