【黃忠成】LINQ首部曲: LINQ To Object Part 2 - Using VB.NET(2)
[程式9]
Sub TestSelectMany()
Dim persons() = { _
New With {.Name = "code6421", .Age = 18, .Address = "Taipai"}, _
New With {.Name = "jeffray", .Age = 18, .Address = "USA"}, _
New With {.Name = "catch", .Age = 18, .Address = "USA"}, _
New With {.Name = "joe", .Age = 18, .Address = "NY"} _
}
Dim p2() = { _
New With {.Title = "Director"}, _
New With {.Title = "Programmer"}, _
New With {.Title = "Manager"} _
}
Dim result = From s1 In persons _
From s2 In p2 _
Select New With {.Name = s1.Name, .Title = s2.Title}
For Each item In result
Console.WriteLine("Name : {0}, Title : {1}", item.Name, item.Title)
Next
Console.ReadLine()
End Sub |
此例的執行結果如圖7。
[圖7]
Name : code6421, Title : Director
Name : code6421, Title : Programmer
Name : code6421, Title : Manager
Name : jeffray, Title : Director
Name : jeffray, Title : Programmer
Name : jeffray, Title : Manager
Name : catch, Title : Director
Name : catch, Title : Programmer
Name : catch, Title : Manager
Name : joe, Title : Director
Name : joe, Title : Programmer
Name : joe, Title : Manager |
Index
LINQ To Object Framework的LINQ Expression允許指定Index,什麼是Index呢 ?請看程式10。
[程式10]
Sub TestIndex()
Dim persons() = { _
New With {.Name = "code6421", .Age = 18, .Address = "Taipai"}, _
New With {.Name = "jeffray", .Age = 18, .Address = "USA"}, _
New With {.Name = "catch", .Age = 18, .Address = "USA"}, _
New With {.Name = "joe", .Age = 18, .Address = "NY"} _
}
Dim result = From s1 In persons Select s1.Name(0)
For Each item In result
Console.WriteLine(item)
Next
Console.ReadLine()
End Sub |
此例會列出陣列中Name屬性值的第一個字元,事實上這是當然的結果,因為where後面的語句,會被VB.NET編譯器當成Lambda Expression處理,而Name屬性是string型態,自然也能對其使用()陣列存取子了,同時也因為是string型別,而且會被轉為Lambda Expression,自然能呼叫屬於string型別的Contains函式了。
Take、TakeWhile
Take函式可以讓設計師由一個IEnumerable物件中取出指定的元素數量,請見程式11。
[程式11]
Sub TestTake()
Dim persons() = { _
New With {.Name = "code6421", .Age = 18, .Address = "Taipai"}, _
New With {.Name = "jeffray", .Age = 18, .Address = "USA"}, _
New With {.Name = "catch", .Age = 18, .Address = "USA"}, _
New With {.Name = "joe", .Age = 18, .Address = "NY"} _
}
Dim result = persons.Take(2)
For Each item In result
Console.WriteLine(item.Name)
Next
Console.ReadLine()
End Sub |
此例會從p1中取出前兩個元素,也就是code6421及jeffray,Take函式的功能有點像是SQL Server的Select TOP。另一個TakeWhile函式則可以讓設計師以while的方式來取出IEnumerable中的元素,請見程式12。
[程式12]
Sub TestTakeWhile()
Dim persons() = { _
New With {.Name = "code6421", .Age = 18, .Address = "Taipai"}, _
New With {.Name = "jeffray", .Age = 18, .Address = "USA"}, _
New With {.Name = "catch", .Age = 18, .Address = "USA"}, _
New With {.Name = "joe", .Age = 18, .Address = "NY"} _
}
Dim result = persons.TakeWhile(Function(p) p.Address = "Taipai")
For Each item In result
Console.WriteLine(item.Name)
Next
Console.ReadLine()
End Sub |
此例的執行結果與Take相同,不同之處在於TakeWhile會一直取出元素,直到某個元素不符合所指定的Lambda Expression為止,這意味著假如指定Address == “USA”時,將不會有任何元素列出,因為陣列中的第一個元素就已經不符合條件了,所以While動作就結束了。
Skip、SkipWhile
相對於Take,Skip允許設計師略過指定的元素數,如程式13。
[程式13]
Sub TestSkip()
Dim persons() = { _
New With {.Name = "code6421", .Age = 18, .Address = "Taipai"}, _
New With {.Name = "jeffray", .Age = 18, .Address = "USA"}, _
New With {.Name = "catch", .Age = 18, .Address = "USA"}, _
New With {.Name = "joe", .Age = 18, .Address = "NY"} _
}
Dim result = (From s1 In persons Select s1).Skip(2)
For Each item In result
Console.WriteLine(item.Name)
Next
Console.ReadLine()
End Sub |
此例會由catch的元素開始列出。另一個SkipWhile函式與TakeWhile的概念相同,SkipWhile也是以While的觀念執行Skip動作,如程式14。
[程式14]
Sub TestSkipWhile()
Dim persons() = { _
New With {.Name = "code6421", .Age = 18, .Address = "Taipai"}, _
New With {.Name = "jeffray", .Age = 18, .Address = "USA"}, _
New With {.Name = "catch", .Age = 18, .Address = "USA"}, _
New With {.Name = "joe", .Age = 18, .Address = "NY"} _
}
Dim result = (From s1 In persons Select s1).SkipWhile(Function(p) p.Address = "Taipai")
For Each item In result
Console.WriteLine(item.Name)
Next
Console.ReadLine()
End Sub |
與TakeWhile一樣,若指定Address == “USA”時,那麼將會列出所有元素,因為在第一個元素時,While就已經結束了。
First、FirstOrDefault
First函式允許設計師指定一個Lambda Expression條件式, 她將以此對IEnumerable(Of T)中的元素查詢,並傳回第一個符合條件的元素,當不指定條件式時,First會傳回第一個元素。與Where不同,First只會傳回符合資料的第一個元素,而非內含所有符合條件元素的IEnumerable(Of T)結果集,見程式15。
[程式15]
Sub TestFirst()
Dim persons() = { _
New With {.Name = "code6421", .Age = 18, .Address = "Taipai"}, _
New With {.Name = "jeffray", .Age = 18, .Address = "USA"}, _
New With {.Name = "catch", .Age = 18, .Address = "USA"}, _
New With {.Name = "joe", .Age = 18, .Address = "NY"} _
}
Dim result = (From s1 In persons Select s1).First()
Console.WriteLine(result.Name)
Console.ReadLine()
End Sub |
下例則是使用條件式的寫法。
Sub TestFirst2()
Dim persons() = { _
New With {.Name = "code6421", .Age = 18, .Address = "Taipai"}, _
New With {.Name = "jeffray", .Age = 18, .Address = "USA"}, _
New With {.Name = "catch", .Age = 18, .Address = "USA"}, _
New With {.Name = "joe", .Age = 18, .Address = "NY"} _
}
Dim result = (From s1 In persons Select s1).First(Function(p) p.Address = "USA")
Console.WriteLine(result.Name)
Console.ReadLine()
End Sub |
當IEnumerable(Of T)中未含有符合條件的元素時,First將會引發例外。另一個FirstOrDefault函式與First函式類似,唯一不同之處是當IEnumerable(Of T)中未含有符合條件之元素時,她將回傳元素之型別的預設值(object為null、數值為0)。與First相對的是Last函式,可取得最後一個元素,她也有另一個同型函式為LastOrDefault,設計理念與FirstOrDefault相同。
ElementAt、ElementAtOrDefault
ElementAt函式可以取得一個物件集中特定位置的元素,如下所示:
Sub TestElementAt()
Dim p1() As String = {"code6421", "tom", "cathy"}
Dim result = p1.ElementAt(1)
Console.WriteLine(result)
Console.ReadLine()
End Sub |
此例會列出tom這個元素,當指定位置超出物件集大小時,ElementAt會丟擲例外。如同FirstOrDefault一般,ElementAt有另一個同型函式:ElementAtOrDefault,當使用此函式時指定位置超出物件集大小時,不會觸發例外,而是直接回傳預設值(object為null,數值為0)。
ToArray、ToList、ToDictionary
這三個函式會將IEnuermable(Of T)轉成Array、List或是Dictionary型別,預設情況下,當我們對某個IEnumerable(Of T)下達Where等條件式時,所取得的結果會是一個IEnumerable(Of T)物件,此時所有條件都尚未執行比對的動作,當對這個IEnumerable(Of T)物件下達MoveNext(For Each會觸發此函式)時,該物件才會進行條件比對。ToArray等函式可以改變此行為模式,當我們對IEnumerable(Of T)物件呼叫這些函式時,其將會以For Each一一巡覽IEnumerable(Of T)物件中的元素並進行條件比對,然後放到另一個結果值後傳回,這也就是說,呼叫此函式所傳回的結果值,將會是已經完成比對後的結果值,操作這個結果集自然比直接操控具條件的結果集來得有效率,程式16是一個使用ToDictionary函式的例子。
[程式16]
Sub TestToDictionary()
Dim persons() = { _
New With {.Name = "code6421", .Age = 18, .Address = "Taipai"}, _
New With {.Name = "jeffray", .Age = 18, .Address = "USA"}, _
New With {.Name = "catch", .Age = 18, .Address = "USA"}, _
New With {.Name = "joe", .Age = 18, .Address = "NY"} _
}
Dim result = persons.ToDictionary(Function(p) p.Name)
Console.WriteLine(result("code6421").Address)
Console.ReadLine()
End Sub |
ToDictionary函式為以指定的鍵值為主鍵,將元素轉為Dictionary物件,此時你可透過預設存取子,以主鍵為引數來取得對應之元素。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-277788/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 【黃忠成】LINQ首部曲: LINQ To Object Part 2 - Using VB.NETObject
- 【黃忠成】LINQ首部曲: LINQ To Object Part 2 - Using VB.NET(3)Object
- LINQ首部曲: LINQ To Object Part 2 - Using VB.NETObject
- LINQ 首部曲 : LINQ To Object Part 1 - Using VB.NET 2008Object
- LINQ系列:Linq to Object投影操作符Object
- LINQ系列:Linq to Object限制操作符Object
- LINQ系列:Linq to Object排序操作符Object排序
- LINQ系列:Linq to Object聚合操作符Object
- LINQ系列:Linq to Object集合操作符Object
- LINQ系列:Linq to Object生成操作符Object
- LINQ系列:Linq to Object元素操作符Object
- LINQ系列:Linq to Object相等操作符Object
- LINQ系列:Linq to Object聯接操作符Object
- LINQ系列:Linq to Object分組操作符Object
- LINQ系列:Linq to Object串聯操作符Object
- LINQ系列:Linq to Object轉換操作符Object
- LINQ系列:Linq to Object量詞操作符Object
- LINQ系列:Linq to Object分割槽操作符Object
- [譯]LINQ TO SQL 介紹(定義資料模型類) – Part.2SQL模型
- LINQ系列:LINQ to XML操作XML
- LINQ系列:LINQ to XML查詢XML
- LINQ系列:LINQ to SQL Take/SkipSQL
- 重學c#系列——linq(2) [二十八]C#
- Linq
- LINQ系列:LINQ to DataSet的DataTable操作
- LINQ系列:LINQ to DataSet的DataView操作View
- LINQ系列:LINQ to SQL Where條件SQL
- LINQ系列:LINQ to SQL Concat/UnionSQL
- LINQ系列:LINQ to SQL Join連線SQL
- 使用LINQ Expression構建Que“.NET研究”ry ObjectExpressObject
- LINQ系列:LINQ to SQL Select查詢SQL
- [MetalKit]3-Using-MetalKit-part-2使用MetalKit2
- [MetalKit]Using ARKit with Metal part 2使用ARKit與Metal 2
- LINQ to SQLSQL
- Lambda、Linq
- LINQ系列:LINQ to SQL Transact-SQL函式SQL函式
- LINQ系列:LINQ to SQL Group by/Having分組SQL
- LINQ系列:C#中與LINQ相關特性C#