How to sort a list in VB.net by a date that is contained within the string

Brian
Brian used Ask the Experts™
on
The code below creates a list of strings that I would like to sort by date, but there are 2 problems. First, the date is within the string, but it can be grabbed by splitting the string and grabbing the 3rd segment - Results(x).Split(""""c)(3). The string is being split by quotes. Second, the date will contain a string like this 7/21/2019 or 11/9/2019. I think this might be an issue because it's not mm/dd/yyyy.  Month or Day could be 1 or 2 characters (not sure if that really matters).

I am thinking DateTime.Compare and DateTime.Parse would be used, but I'm not sure how I would use them to get the list in order of date. The list will contain strings that look like this...

"-419.56","7/9/2019","Company","Product","RAS-201459"

In the code below, the date for the first item in the List is outputted, but I want to sort the List by date. Does someone know how this can be done? Thanks!

    Private Sub btnSaveReport_Click(sender As Object, e As EventArgs) Handles btnSaveReport.Click
        Try
            Dim strSourceFileLocation As String = AppDomain.CurrentDomain.BaseDirectory + "_data/"
            Dim strDetinationFileLocation As String = tbSaveFileLocation.Text
            Dim Paths() As String = IO.Directory.GetFiles(strSourceFileLocation, "*.code")
            Dim Results As New List(Of String)()
            For Each Path As String In Paths
                For Each line As String In File.ReadAllLines(Path)
                    If line.Contains("RAS-") Then
                        Results.Add(line)
                    End If
                Next line
            Next
            Dim strDate As String = Results(0).Split(""""c)(3)
            MsgBox(strDate)
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
        Me.Close()
    End Sub

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Éric MoreauSenior .Net Consultant
Top Expert 2016

Commented:
Converting the segment to a date is the easy part if it is always the same format. You can use TryParseExact as shown in https://docs.microsoft.com/en-us/dotnet/api/system.datetime.tryparseexact?view=netframework-4.8
BrianSystems Administrator

Author

Commented:
I was testing the date format I have and DateTime.Compare works fine without using parse (see below). So the date format won't be a problem, but how can I sort the List by the date? Would it require recursion to do this, or is there an easier way?

            MsgBox(DateTime.Compare("12/11/2019", "7/8/2019"))      returns  1
            MsgBox(DateTime.Compare("7/6/2019", "7/18/2019"))        returns -1
            MsgBox(DateTime.Compare("1/11/2019", "11/8/2019"))      returns -1
            MsgBox(DateTime.Compare("9/5/2019", "7/8/2019"))          returns  1
            MsgBox(DateTime.Compare("10/11/2019", "11/28/2019")) returns -1
Éric MoreauSenior .Net Consultant
Top Expert 2016

Commented:
dates would need to be extracted and placed in a list or dictionary of some sort. then you can sort that list.
Bootstrap 4: Exploring New Features

Learn how to use and navigate the new features included in Bootstrap 4, the most popular HTML, CSS, and JavaScript framework for developing responsive, mobile-first websites.

Éric MoreauSenior .Net Consultant
Top Expert 2016

Commented:
have a look at https://www.dotnetperls.com/dictionary-vbnet for a dictionary. your key could be your date while the value could be your full string.
Commented:
You would do something like this:
Private Sub btnSaveReport_Click(sender As Object, e As EventArgs) Handles btnSaveReport.Click
    Try
        Dim strSourceFileLocation As String = AppDomain.CurrentDomain.BaseDirectory + "_data/"
        Dim strDetinationFileLocation As String = tbSaveFileLocation.Text
        Dim Paths() As String = IO.Directory.GetFiles(strSourceFileLocation, "*.code")
        Dim Results As New List(Of String)()
        For Each Path As String In Paths
            For Each line As String In File.ReadAllLines(Path)
                If line.Contains("RAS-") Then
                    Results.Add(line)
                End If
            Next line
        Next
        Dim strDate As String = Results.OrderBy(Function(x) DateTime.Parse(x.Split(""""c)(3)))(0)
        MsgBox(strDate)
    Catch ex As Exception
        MessageBox.Show(ex.Message)
    End Try
    Me.Close()
End Sub

Open in new window

Proof of concept:
Imports System

Module Program
    Sub Main(args As String())
        Dim paths = From i In Enumerable.Range(0, 40)
                    Select $"RAS-ABCD-{DateTime.Now.AddDays(-(9 * i + 1)).ToShortDateString()}-DCBA-SAR"

        Dim sorted = paths.OrderBy(Function(x) DateTime.Parse(x.Split("-")(2)))

        Console.WriteLine("First Five Unsorted: ")
        Console.WriteLine(String.Join(Environment.NewLine, paths.Take(5)))

        Console.WriteLine()
        Console.WriteLine("First Five Sorted: ")
        Console.WriteLine(String.Join(Environment.NewLine, sorted.Take(5)))

        Console.ReadLine()
    End Sub
End Module

Open in new window

Which produces the following output -Capture.PNG-saige-
BrianSystems Administrator

Author

Commented:
Saige, that is awesome! I've been working away on Eric's concept of extracting the dates, but your way is much more concise than what I have! I'll replace my code with yours and see how it works. Thanks!

    Private Sub btnSaveReport_Click(sender As Object, e As EventArgs) Handles btnSaveReport.Click
        Dim strSourceFileLocation As String = AppDomain.CurrentDomain.BaseDirectory + "_data/"
        Dim strDetinationFileLocation As String = tbSaveFileLocation.Text
        Dim Paths() As String = IO.Directory.GetFiles(strSourceFileLocation, "*.code")
        Dim Results As New List(Of String)()
        Dim dateList As New List(Of Date)
        Dim finalList As New List(Of String)
        Dim strDateList As New List(Of String)
        Dim strInList As String = ""
        Try
            For Each Path As String In Paths
                For Each line As String In File.ReadAllLines(Path)
                    If line.Contains("RAS-") Then
                        Results.Add(line)
                    End If
                Next line
            Next
            Dim strDate As String = Results(0).Split(""""c)(3)

        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try

        Try
            If Not Results Is Nothing Then '// Do not process if list is empty
                Dim strPrevious As String = ""
                Dim strNew As String = ""
                For Each strInList In Results
                    dateList.Add(strInList.Split(""""c)(3))
                Next
                dateList.Sort()
            End If
            dateList = dateList.Distinct.ToList

            For Each strDateInList In dateList
                For Each strInList In Results
                    If strInList.Split(""""c)(3) = strDateInList Then
                        finalList.Add(strInList)
                    End If
                Next
            Next
            strInList = ""
            For Each strInList In finalList
                MsgBox(strInList)
            Next
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
        Me.Close()
    End Sub

Open in new window

BrianSystems Administrator

Author

Commented:
Saige, that works awesome and is so concise! Thanks so much for the help!

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial