Results 1 to 19 of 19

Thread: Create a List for multiple entries

  1. #1

    Thread Starter
    Lively Member
    Join Date
    Apr 2021
    Posts
    69

    Create a List for multiple entries

    I need to create a List to store multiple values like following example:

    I need to loop through all filenames in a folder.
    I compare the filename against keywords. When the keyword exists in the filename we want to store
    both the keyword and the filename to a List, for example:

    "this is a beautiful filename.doc" <-> keyword "beautiful"
    we store filename and keyword beautiful

    "this is also a beautiful next filename.doc" <-> keyword "beautiful" and keyword "next"
    we store filename and keyword beautiful and next

    I am kind of lost because later on I want to return for example all filenames that match the keyword "beautiful"

    Code:
    ReadOnly values As Dictionary(Of String, String) = New Dictionary(Of String, String)()

  2. #2
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    36,257

    Re: Create a List for multiple entries

    Well, you're on the right track. What I'd use is a Dictionary(of String, List(of String))

    For each key, there would be a List(of String) holding all the filenames.
    My usual boring signature: Nothing

  3. #3

    Thread Starter
    Lively Member
    Join Date
    Apr 2021
    Posts
    69

    Re: Create a List for multiple entries

    Quote Originally Posted by Shaggy Hiker View Post
    Well, you're on the right track. What I'd use is a Dictionary(of String, List(of String))

    For each key, there would be a List(of String) holding all the filenames.
    I created as you suggested:

    Code:
    ReadOnly files As Dictionary(Of String, List(Of String)) = New Dictionary(Of String, List(Of String))()
    
                    If Not files.ContainsKey(sCountry) Then
                        files.Add(sCountry, New List(Of String))
                        files(sCountry).Add(sFile)
                    Else
                        files(sCountry).Add(sFile)
                    End If
    If I want to retrieve all files with a certain country code?
    Last edited by clausowitz; May 7th, 2021 at 12:41 PM.

  4. #4
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Location
    South Louisiana
    Posts
    10,317

    Re: Create a List for multiple entries

    You should check if the country code exists in the dictionary, if so then get the value (i.e. List):
    Code:
    Dim countryCode = "USA"
    If (files.ContainsKey(countryCode)) Then
        Dim files = files(countryCode)
    
        Console.WriteLine(String.Join(", ", files.ToArray()))
    End If
    "Code is like humor. When you have to explain it, itís bad." - Cory House
    VbLessons | Code Tags | Sword of Fury - Jameram

  5. #5

    Thread Starter
    Lively Member
    Join Date
    Apr 2021
    Posts
    69

    Re: Create a List for multiple entries

    Quote Originally Posted by dday9 View Post
    You should check if the country code exists in the dictionary, if so then get the value (i.e. List):
    Code:
    Dim countryCode = "USA"
    If (files.ContainsKey(countryCode)) Then
        Dim files = files(countryCode)
    
        Console.WriteLine(String.Join(", ", files.ToArray()))
    End If
    I tried following:

    Code:
    For Each kvp In files
    If kvp.Key = sCountries Then
       For Each Str In kvp.Value
    
       Next
    End If
    Next
    Which works better?

  6. #6
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    24,033

    Re: Create a List for multiple entries

    Try this...

    Code:
    Dim values As New Dictionary(Of List(Of String), List(Of String))
    Dim keywords() As String = {"beautiful", "next"}
    Dim lines() As String = {"this is a beautiful filename.doc", _
                                     "this is also a beautiful next filename.doc"}
    
    
    For Each line As String In lines
        Dim foundKeywords As New List(Of String)
        For Each keyword As String In keywords
            If line.Contains(keyword) Then
                foundKeywords.Add(keyword)
            End If
        Next
        Dim found As Boolean = False
        For Each kvp As KeyValuePair(Of List(Of String), List(Of String)) In values
            If kvp.Key.SequenceEqual(foundKeywords) Then
                kvp.Value.Add(line)
                found = True
                Exit For
            End If
        Next
        If foundKeywords.Count > 0 AndAlso Not found Then
            values.Add(foundKeywords, New List(Of String)(New String() {line}))
        End If
    Next
    ***CODE EDITED***
    Last edited by .paul.; May 7th, 2021 at 03:37 PM.

  7. #7
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    107,130

    Re: Create a List for multiple entries

    Quote Originally Posted by clausowitz View Post
    I tried following:

    Code:
    For Each kvp In files
    If kvp.Key = sCountries Then
       For Each Str In kvp.Value
    
       Next
    End If
    Next
    Which works better?
    Definitely not that. It defeats the purpose of a Dictionary, which is fast lookup.

  8. #8
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    24,033

    Re: Create a List for multiple entries

    Quote Originally Posted by jmcilhinney View Post
    Definitely not that. It defeats the purpose of a Dictionary, which is fast lookup.
    But the OP wants a List(of String) as the key...

  9. #9
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    107,130

    Re: Create a List for multiple entries

    Quote Originally Posted by .paul. View Post
    But the OP wants a List(of String) as the key...
    I don't see that. There's no reason that a single file path can't be added to multiple values if that file contains multiple keywords. The OP said that they want to get all the files containing a specific keyword, so it would seem that each key would be a single keyword.

  10. #10
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    24,033

    Re: Create a List for multiple entries

    Quote Originally Posted by jmcilhinney View Post
    I don't see that. There's no reason that a single file path can't be added to multiple values if that file contains multiple keywords. The OP said that they want to get all the files containing a specific keyword, so it would seem that each key would be a single keyword.
    Yes. That sounds like a better plan. A Dictionary(of String, List(of String))

  11. #11
    PowerPoster ChrisE's Avatar
    Join Date
    Jun 2017
    Location
    Frankfurt
    Posts
    2,815

    Re: Create a List for multiple entries

    I would search the folder first for Files that contain any of the keywords and count later. I don't know how many Files you
    have in the folder.
    might be quicker that way, first the search and then the count, or it won't make much diffrence

    here to find with keywords
    Code:
    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
            Dim folderToSearch = "d:\check"
            Dim stringToFind = New List(Of String) From {"Result", "Test1", "Test2"}
            Dim stringInfiles = (New DirectoryInfo(folderToSearch)).GetFiles().Where(Function(file) stringToFind.Any(Function(condition) file.Name.IndexOf(condition) > -1)).ToList()
            stringInfiles.ForEach(Sub(file) ListBox1.Items.Add(file.Name))
        End Sub
    to hunt a species to extinction is not logical !
    since 2010 the number of Tigers are rising again in 2016 - 3900 were counted. with Baby Callas it's 3901, my wife and I had 2-3 months the privilege of raising a Baby Tiger.

  12. #12

    Thread Starter
    Lively Member
    Join Date
    Apr 2021
    Posts
    69

    Re: Create a List for multiple entries

    Let me give some clarification for what I do.
    I have an archive of about 4000 documents. With the code I loop through all the filenames and search for country names.
    When I find a country that I want to save I store the name of the country if it doesn't already exists in the list and add the filename that contains the country name.

    Therefor I created a dictionary:
    Code:
    Public files As Dictionary(Of String, List(Of String)) = New Dictionary(Of String, List(Of String))()
    
    sFile = "my first filename USA.doc"
    sCountry = "USA"
    
    If Not files.ContainsKey(sCountry) Then
          files.Add(sCountry, New List(Of String))
          files(sCountry).Add(sFile)
    Else
          files(sCountry).Add(sFile)
    End If
    After this I select a country name from a Listview and open a form in Dialog.

    Code:
    Public Overloads Function ShowDialog(ByVal sCountry As String) As String
            sCountries = sCountry
            MyBase.ShowDialog()
    End Function
    then I select all the records from a database that contains details of all documents and show them in a Listview

    Code:
           For Each kvp In files
                'find all records for the chosen country
                If kvp.Key = sCountries Then
                    For Each Str In kvp.Value
    
                         Dim row As DataRow
                        For Each row In dt1.Rows
                             If Str = row.Item("Document Name") Then
                                i += 1
                                sName = row.Item("Document Name")
                                sType = row.Item("Document Type")
                                sPath = row.Item("Document Location")
                                iId = row.Item("Id")
    
                                ListView1.Items.Add(New ListViewItem(New String() {"", sName.ToString, sPath.ToString, iId.ToString}, docImage))
                            End If
                        Next
                    Next
                End If
            Next
    Although it is functioning I am curious to know if there is a more effective way to do this

  13. #13
    PowerPoster ChrisE's Avatar
    Join Date
    Jun 2017
    Location
    Frankfurt
    Posts
    2,815

    Re: Create a List for multiple entries

    I use a Powershell script to:
    1) read all the Filenames is a Folder
    2) create a .csv File from that
    3) read that .csv File to a Database Table
    4) perform SQL Query for my search

    I don't know if that is an option for you
    here a Image of what the Database table looks like after Import

    Name:  FileDB.jpg
Views: 63
Size:  25.4 KB
    to hunt a species to extinction is not logical !
    since 2010 the number of Tigers are rising again in 2016 - 3900 were counted. with Baby Callas it's 3901, my wife and I had 2-3 months the privilege of raising a Baby Tiger.

  14. #14

    Thread Starter
    Lively Member
    Join Date
    Apr 2021
    Posts
    69

    Re: Create a List for multiple entries

    Chris,

    does this also store which strings were found?
    When retrieving I want to be able to select all files that contain "Test1"

  15. #15

    Thread Starter
    Lively Member
    Join Date
    Apr 2021
    Posts
    69

    Re: Create a List for multiple entries

    Chris,

    does this also store which strings were found?
    When retrieving I want to be able to select all files that contain "Test1"

    Code:
    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
            Dim folderToSearch = "d:\check"
            Dim stringToFind = New List(Of String) From {"Result", "Test1", "Test2"}
            Dim stringInfiles = (New DirectoryInfo(folderToSearch)).GetFiles().Where(Function(file) stringToFind.Any(Function(condition) file.Name.IndexOf(condition) > -1)).ToList()
            stringInfiles.ForEach(Sub(file) ListBox1.Items.Add(file.Name))
        End Sub

  16. #16
    PowerPoster ChrisE's Avatar
    Join Date
    Jun 2017
    Location
    Frankfurt
    Posts
    2,815

    Re: Create a List for multiple entries

    Quote Originally Posted by clausowitz View Post
    Chris,

    does this also store which strings were found?
    When retrieving I want to be able to select all files that contain "Test1"

    Code:
    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
            Dim folderToSearch = "d:\check"
            Dim stringToFind = New List(Of String) From {"Result", "Test1", "Test2"}
            Dim stringInfiles = (New DirectoryInfo(folderToSearch)).GetFiles().Where(Function(file) stringToFind.Any(Function(condition) file.Name.IndexOf(condition) > -1)).ToList()
            stringInfiles.ForEach(Sub(file) ListBox1.Items.Add(file.Name))
        End Sub
    don't know what you mean, you see the found Files in the Listbox
    to hunt a species to extinction is not logical !
    since 2010 the number of Tigers are rising again in 2016 - 3900 were counted. with Baby Callas it's 3901, my wife and I had 2-3 months the privilege of raising a Baby Tiger.

  17. #17

    Thread Starter
    Lively Member
    Join Date
    Apr 2021
    Posts
    69

    Re: Create a List for multiple entries

    What I mean is.
    Your Listbox1 contains all files that matched one of the criteria (Test1, Test2 etc.)
    How can I see which criteria was found in what file?

  18. #18
    PowerPoster ChrisE's Avatar
    Join Date
    Jun 2017
    Location
    Frankfurt
    Posts
    2,815

    Re: Create a List for multiple entries

    Quote Originally Posted by clausowitz View Post
    What I mean is.
    Your Listbox1 contains all files that matched one of the criteria (Test1, Test2 etc.)
    How can I see which criteria was found in what file?
    that's what I meant by Count afterwords.
    it would find files with one or all three search strings
    to hunt a species to extinction is not logical !
    since 2010 the number of Tigers are rising again in 2016 - 3900 were counted. with Baby Callas it's 3901, my wife and I had 2-3 months the privilege of raising a Baby Tiger.

  19. #19
    Frenzied Member
    Join Date
    Jul 2011
    Location
    UK
    Posts
    1,335

    Re: Create a List for multiple entries

    Quote Originally Posted by clausowitz View Post
    When retrieving I want to be able to select all files that contain "Test1"
    If you want to store and retrieve a chunk of data based on a keyword, then a Dictionary is a good choice. You had one set up in Post #12.

    However, to retrieve values you do not iterate through the key value pairs. Dictionaries leverage a hash table which makes all look-ups O(1) operations instead of O(n) at worst when iterating. To fetch data it's simply value = dictionary(key).

    So your current code:
    Code:
    For Each kvp In files
        'find all records for the chosen country
        If kvp.Key = sCountries Then
            For Each Str As String In kvp.Value
    
                ' If the datatable happens to contain a record for this filename (Str)
                ' then display the record data in the ListView
    
            Next
        End If
    Next
    becomes:
    Code:
    Public files As Dictionary(Of String, List(Of String)) = New Dictionary(Of String, List(Of String))()
    
    sFile = "my first filename USA.doc"
    sCountry = "USA"
    
    If Not files.ContainsKey(sCountry) Then
          files.Add(sCountry, New List(Of String))
          files(sCountry).Add(sFile)
    Else
          files(sCountry).Add(sFile)
    End If
    Code:
    sCountry = "USA"
    Code:
    Dim countryFileNames As List(Of String) = files(sCountry)
    
    For Each fileName In countryFileNames
    
        ' If the datatable happens to contain a record for this filename
        ' then display the record data in the ListView
    
    Next
    and of course those first two lines can be simplified into one so as to reduce clutter:
    For Each fileName In files(sCountry)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width