Welcome to Dream.In.Code
Getting Help is Easy!

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!




Using LINQ

 
Reply to this topicStart new topic

> Using LINQ, Requires .NET 3.5 & above

AdamSpeight2008
Group Icon



post 28 Aug, 2008 - 12:29 AM
Post #1


Requires .Net Framework 3.5

What is LINQ?
Language INtegrated Query

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

TheEvents.Add(New DatumEvent(New Date(2008, 8, 24, 7, 0, 0), New Date(2008, 8, 24, 15, 0, 0), "Work Shift", System.Drawing.Color.Red))
TheEvents.Add(New DatumEvent(New Date(2008, 8, 26, 15, 0, 0), New Date(2008, 8, 26, 23, 0, 0), "Work Shift", System.Drawing.Color.DarkBlue))
TheEvents.Add(New DatumEvent(New Date(2008, 8, 30, 15, 0, 0), New Date(2008, 8, 30, 23, 0, 0), "Work Shift", System.Drawing.Color.Yellow))
TheEvents.Add(New DatumEvent(New Date(2008, 8, 31, 15, 0, 0), New Date(2008, 8, 31, 23, 0, 0), "Work Shift", System.Drawing.Color.Red))
TheEvents.Add(New DatumEvent(New Date(2008, 9, 1, 15, 0, 0), New Date(2008, 9, 1, 23, 0, 0), "Work Shift", System.Drawing.Color.Red))
TheEvents.Add(New DatumEvent(New Date(2008, 9, 2, 15, 0, 0), New Date(2008, 9, 2, 23, 0, 0), "Work Shift", System.Drawing.Color.Red))
DrawEvents(Me.PictureBox1, New Date(2008, 8, 23, 0, 0, 0), 1, 9)
DrawEvents(Me.PictureBox2, New Date(2008, 8, 25, 0, 0, 0), 1, 1)

End Sub

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.

So now you too can be a LINQ using code-ninja ph34r.gif
Go to the top of the page
+Quote Post


Register to Make This Ad Go Away!

AdamSpeight2008
Group Icon



post 11 Sep, 2008 - 06:32 PM
Post #2
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
Go to the top of the page
+Quote Post

AdamSpeight2008
Group Icon



post 13 Sep, 2008 - 08:04 PM
Post #3
The following correction to the DatumEvent Class in the First Example, correctly computes a variation of Julian Date.
vb

Private Function JDate(ByVal ThisDate As DateTime) As Double
Return ThisDate.Subtract(New Date(1, 1, 1, 0, 0, 0)).TotalDays
End Function

Go to the top of the page
+Quote Post

AdamSpeight2008
Group Icon



post 2 Nov, 2008 - 03:05 AM
Post #4
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
Go to the top of the page
+Quote Post

AdamSpeight2008
Group Icon



post 3 Nov, 2008 - 10:59 PM
Post #5
Counts of Words
vb

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
Go to the top of the page
+Quote Post

AdamSpeight2008
Group Icon



post 17 Nov, 2008 - 03:57 PM
Post #6
Get the difference between two lists.
CODE

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"}
Go to the top of the page
+Quote Post


Fast ReplyReply to this topicStart new topic
2 User(s) are reading this topic (2 Guests and 0 Anonymous Users)
0 Members:

 

Lo-Fi Version Time is now: 12/2/08 08:51AM

Live Help!

Tutorials

Programming

Web Development

Reference Sheets

Code Snippets

DIC Chatroom

Bye Bye Ads

Monthly Drawing

Thumb Drive

Top Contributors

Top 10 Kudos This Month