Join 136,352 Programmers for FREE! Get instant access to thousands of experts, tutorials, code snippets, and more! There are 2,720 people online right now. Registration is fast and FREE... Join Now!
What does it do? Lets you use SQL queries on Objects, mainly arrays.
Simple example -Find all of the words the contain AR and put them in Alphabetical order.
vb
Dim words() As String = {"DOG", "CARROT", "APPLE", "AARDVARK", "ELEPHANT"} Dim TheLINQ_Matches As IEnumerable(Of String) TheLINQ_Matches = From TheWord As String In words Where TheWord Like "*AR*" Order By TheWord Ascending For Each Word As String In TheLINQ_Matches Console.WriteLine(Word) Next
It can be used on class objects too. For example this one which is handles date events.
vb
Public Class DatumEvent
Private mStartTime As DateTime Private mJStart As Double Public Property StartTime() As DateTime Get Return mStartTime End Get Set(ByVal value As DateTime) mStartTime = value mJStart = JDate(mStartTime) End Set End Property Private mFinishTime As DateTime Private mJFinish As Double
Public Property FinishTime() As DateTime Get Return mFinishTime End Get Set(ByVal value As DateTime) mFinishTime = value mJFinish = JDate(mFinishTime)
End Set End Property
Public ReadOnly Property StartTime_Julian() As Double Get Return mJStart End Get End Property
Public ReadOnly Property FinishTime_Julian() As Double Get Return mJFinish End Get End Property
Public ReadOnly Property Delta_TimeSpan() As TimeSpan Get Return mFinishTime.Subtract(mStartTime) End Get End Property
Public ReadOnly Property Delta_Julian() As Double Get Return mJFinish - mJStart 'JDate(mFinishTime) - JDate(mStartTime) End Get End Property
Private mEventText As String Public Property EventText() As String Get Return mEventText End Get Set(ByVal value As String) mEventText = value End Set End Property Private mEventColor As System.Drawing.Color
Public Property EventColor() As System.Drawing.Color Get Return mEventColor End Get Set(ByVal value As System.Drawing.Color) mEventColor = value End Set End Property
Private Function JDate(ByRef thisdate As DateTime) As Double Dim a As Double = Math.Floor((14 - thisdate.Month) / 14) Dim y As Double = thisdate.Year + 4800 - a Dim m As Double = thisdate.Month + (12 * a) - 3 Dim jdn As Double = 0 jdn = thisdate.Day + Math.Floor(((153 * m) + 2) / 5) + (365 * y) + Math.Floor(y / 4) - Math.Floor(y / 100) + Math.Floor(y / 400) - 32045 jdn += ((thisdate.Hour - 12) / 24) + (thisdate.Minute / 1440) + (thisdate.Second / 86400) Return jdn End Function
Public Sub New(ByRef Start As DateTime, ByRef Finish As DateTime, ByRef Text As String,ByRef color As System.Drawing.Color) StartTime = Start FinishTime = Finish EventText = Text EventColor = color End Sub End Class
Utilized by the following program.
vb
Public Class Form1 Dim TheEvents As New List(Of DatumEvent) Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Public Sub DrawEvents(ByRef a As PictureBox, ByVal s As DateTime, ByVal DayWidth As Double, ByRef DayHeight As Double) Dim l As New TimeSpan(DayHeight * DayWidth, 0, 0, 0) Dim bmp As New Bitmap(a.Width, a.Height) Dim HeightOfRow As Double = a.Height / DayHeight Dim pg As Graphics = Graphics.FromImage(bmp) pg.Clear(Color.White) Dim FirstDatum As New DatumEvent(s, s, "", System.Drawing.Color.Black) Dim VerticalOffset As Double = 0 Dim EventsMatches As IEnumerable(Of DatumEvent) For i = 0 To DayHeight - 1
It even can handle complex searches like to one below. Find all the events the that start or in progress between the start date & time and the finish date & time.
CODE
' Using LINQ find all Events Start and End DateTImes EventsMatches = From item In TheEvents _ Select item _ Where ((item.StartTime >= s) Or (item.StartTime.Add(item.Delta_TimeSpan) >= s)) _ And ((item.StartTime < s.AddDays(DayWidth)) Or (item.StartTime.Add(item.Delta_TimeSpan) < s.AddDays(DayWidth)))
All that in 1 Line of code.
vb
' For Each Matching Evetn draw it For Each MatchingEvent As DatumEvent In EventsMatches DrawEvent(pg, FirstDatum, MatchingEvent, DayWidth, VerticalOffset, HeightOfRow, DayWidth * i) Next ' Update Vertical offset VerticalOffset += HeightOfRow ' Adjust Start date for next row s = s.AddDays(DayWidth) Next i ' Stick the created bitmap into it picture box a.Image = bmp End Sub
Finally the code that draws the event.
vb
Public Sub DrawEvent( _ ByRef g As Graphics, _ ByVal TheDatumEvent As DatumEvent, _ ByRef ThisEvent As DatumEvent, _ ByVal DaysWide As Double, _ ByVal VertialOffset As Double, _ ByVal HeightOfRow As Double, _ ByVal DayWidthValue As Double _ ) Dim JulianStartOffset As Double = (ThisEvent.StartTime_Julian - TheDatumEvent.StartTime_Julian) Dim JulianEventWidth As Double = JulianStartOffset + ThisEvent.Delta_Julian Dim EventRect As New RectangleF( _ (JulianStartOffset - DayWidthValue) * (g.VisibleClipBounds.Width / DaysWide), _ VertialOffset, _ ThisEvent.Delta_Julian * (g.VisibleClipBounds.Width / DaysWide), _ HeightOfRow) Using p As New Pen(ThisEvent.EventColor) ' Draw Rectangle g.FillRectangle(p.Brush, EventRect.X, EventRect.Y, EventRect.Width, EventRect.Height) ' Draw the border g.DrawRectangle(Pens.Black, EventRect.X, EventRect.Y, EventRect.Width, EventRect.Height) End Using
End Sub End Class
So Basics are Dim Results As IEnumerable(Of <The Type or Class>) Results = SELECT item WHERE <SQL STATEMENT> Note item is very useful on Lists.
Using LINQ to calculate the Average Imagine we need calculate the average speed of a number of runs. So you define a class object to store the details of each run.
vb
Public Class MyRun Private mRunDate As Date Public Property RunDate() As Date Get Return mRunDate End Get Set(ByVal value As Date) mRunDate = value End Set End Property Private mRunDist As Double Public Property RunDist() As Double Get Return mRunDist End Get Set(ByVal value As Double) mRunDist = value End Set End Property Private mRunTime As Double Public Property RunTime() As Double Get Return mRunTime End Get Set(ByVal value As Double) mRunTime = value End Set End Property
Protected Overrides Sub Finalize() MyBase.Finalize() End Sub
Public Sub New(ByVal DateOfRun As Date, ByVal RunKms As Double, ByVal RunMins As Double) RunDate = DateOfRun RunDist = RunKms RunTime = RunMins End Sub End Class
Add in a few runs, and calculate the average speed.
vb
Public Class Form1 Dim Runs As New List(Of MyRun) Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 'Distance(km) 5 4 5 5 5 5 29 'Time (mins) 18.7 17.3 18.3 20 18.8 19.3 112.4 Runs.Add(New MyRun(New Date(2008, 9, 1), 5, 18.7)) Runs.Add(New MyRun(New Date(2008, 9, 2), 4, 17.3)) Runs.Add(New MyRun(New Date(2008, 9, 3), 5, 18.3)) Runs.Add(New MyRun(New Date(2008, 9, 4), 5, 20)) Runs.Add(New MyRun(New Date(2008, 9, 5), 5, 18.8)) Runs.Add(New MyRun(New Date(2008, 9, 6), 5, 19.3)) Console.WriteLine(AverageKph) End Sub
Private Function AverageKph() As Double Return (Aggregate item As MyRun In Runs Into Sum(item.RunDist)) / (Aggregate item As MyRun In Runs Into Sum(item.RunTime)) * 60 End Function End Class
How do the AverageKph Function work? Basically it is perform the follow sum
SUM OF DISTANCES ----------------------- = KmPerMinute SUM OF TIMES
since we want Kph, it need to be multiplied by 60.
Advance Average Now we only calculate the average speed between to dates.
vb
Private Function AverageKphForDate(ByVal FromD As Date, ByVal ToD As Date) As Double If FromD.CompareTo(ToD) > 0 Then Throw New Exception("From Date can not be after ToDate") End If Dim RunBetweenDates As IEnumerable(Of MyRun) RunBetweenDates = From item As MyRun In Runs Select item Where (item.RunDate >= FromD And item.RunDate <= ToD) Dim avg As Double = (Aggregate item As MyRun In RunBetweenDates Into Sum(item.RunDist)) / (Aggregate item As MyRun In RunBetweenDates Into Sum(item.RunTime)) * 60 If Double.IsNaN(avg) Then Return 0 Return avg End Function
Calculate the Distribution Of Letters In A Sentence
vb
Dim TheSentence As String = "ABCDEFGHIJKLMNOPQRTSUVWXYZA" Dim Alphabet As String = "ABCDEFGHIJKLMNOPQRTSUVWXYZ" Dim LetterCounts As IEnumerable(Of Integer) = From Letter In TheSentence, Alphabet_Letter In Alphabet.Distinct _ Where Char.ToUpper(Letter) = Alphabet_Letter _ Group Letter By Alphabet_Letter Into LetterGroups = Group Select LetterGroups.Count For i As Integer = 0 To LetterCounts.Count - 1 Console.WriteLine("{0} => {1}", TheSentence(i), LetterCounts(i)) Next
Private Sub CountWords() Dim TheSentence As String = "THE QUICK BROWN FOX LEAPED OVER THE LAZY BROWN DOG" Dim WordCounts As IEnumerable = From TheWords In TheSentence.Split(" ").ToList, DistinctWords In TheSentence.Split(" ").ToList.Distinct.ToList _ Where TheWords.ToUpper = DistinctWords.ToUpper _ Group TheWords By DistinctWords Into CountsOfLetters = Group Select Word = DistinctWords, Number = CountsOfLetters.Count
For Each i In WordCounts Console.WriteLine("Word: {0} Count:{1}", i.Word.ToString, i.Number.ToString) Next End Sub
Edited: To Add Explanation
Take the sentence and split (at the spaces) it into a list of words TheWords Do the same but this them removing duplicates DistinctWords Find all the words in TheWords that have a match in DistinctWords group them by DistinctWords Count the number of items in each group.
This post has been edited by AdamSpeight2008: 3 Nov, 2008 - 11:55 PM
Dim servers() As String = {"A", "B", "C", "D"} Dim localFiles() As String = {"D", "B"} Dim downloadfile As IEnumerable(Of String) = servers.Except(localFiles.AsEnumerable) ' downloadfile -> {"A","C"}