Compare Array string to file name

I am able to create an array of string’s by reading a text file. I am now attempting to do is a file listing, determine if the file.name is in the array, and if it is, write it out to my listbox. However, when I do that, I can see all the names in my array, but the listbox just gets filled with repeated names and paths from the array and not the file.name and file.native path from my file search. Here is my code:

PopulateArray

// This populates the listbox with just the file types you want to convert
if theFolder<>nil then
  if theFolder.Directory AND NOT theFolder.isApplicationMBS Then
    for i as Integer=1 to theFolder.Count
      if theFolder.Item(i).Directory AND theFolder.Item(i).name.Right(4) = ".key" = False AND theFolder.Item(i).name.Right(6) = ".pages" = False _
         AND theFolder.Item(i).name.Right(8) = ".numbers" = False Then
        ListFiles(theFolder.Item(i))
      else
        if theFolder.Item(i).Name = ".DS_Store" = False AND theFolder.Item(i).Name = "Thumbs.db" = False AND theFolder.Item(i).Name = ".localized" = False Then
          'resultsLB.AddRow (theFolder.Item(i).Name, theFolder.Item(i).NativePath)
          For n As Integer = 0 To TextArray.Ubound
            if str(TextArray(n)) = theFolder.Item(i).Name Then
              resultsLB.AddRow (theFolder.Item(i).Name, theFolder.Item(i).NativePath)
            end if
          Next
        end if
      end if
      
    next
    
  else
    if theFolder<>nil then
      if theFolder.Directory then
        if theFolder.DisplayName.Right(4) = ".key"  OR theFolder.DisplayName.Right(6) = ".pages" OR _
           theFolder.DisplayName.Right(8) = ".numbers" AND theFolder.isBundleMBS Then
          'resultsLB.AddRow (theFolder.Name, theFolder.NativePath)
        end if
      end if
    end if
  end if
end if

Any help would be greatly appreciated.

Put the filenames you want to check into a dictionary

Check the ones on disc to see if thedictionary.haskey(thefilename)
If its in the dictionary, display it.
Much faster than looping through an array over and over

[code]DIM index As Integer = array.IndexOf(whatYouWantToFind)

if (index = -1) then
// not found
else
// found and the index variable is the array index, incase you need to use it
// DIM path As Xojo.IO.FolderItem = array(index) ’ just an example
end if[/code]

The dictionary idea is the same, but you can store the file name or path as the key and the other as the value…

Thanks to both for the response. I am trying to figure out how to get each line of a text file into a dictionary. I have a property created called MyDictionary and I have an instance of a new dictionary being created when the application opens. Just trying to figure out how to populate from a text file.

Xojo.IO.TextInputStream.Open or TextInputStream.Open … You can either .ReadAll and then parse the text/string in to the dictionary, or you can loop over the file and .ReadLine and just cram the data in to the dictionary right away,

It appears I have done this correctly using the .ReadLine, but how do I get a MsgBox to display the lines in the dictionary to make sure.? There are only 3 that I need to check for this purpose.

I would just use a break once your done and take a look at the dictionary

Thanks Shao. I was able to verify that my dictionary contains all the file names I am looking for, but now I get nothing to display in my listbox. Can you take a look and tell me what I am doing wrong? Here is the code:

// This populates the listbox with just the file types you want to convert
if theFolder<>nil then
  if theFolder.Directory AND NOT theFolder.isApplicationMBS Then
    for i as Integer=1 to theFolder.Count
      if theFolder.Item(i).Directory AND theFolder.Item(i).name.Right(4) = ".key" = False AND theFolder.Item(i).name.Right(6) = ".pages" = False _
        AND theFolder.Item(i).name.Right(8) = ".numbers" = False Then
        ListFiles(theFolder.Item(i))
        
        if MyDictionary.HasKey(theFolder.Item(i).Name) Then
          resultsLB.AddRow (theFolder.Item(i).Name, theFolder.Item(i).NativePath)
        end if
      end if
    next
    
  else
    if theFolder<>nil then
      if theFolder.Directory then
        if theFolder.DisplayName.Right(4) = ".key"  OR theFolder.DisplayName.Right(6) = ".pages" OR _
          theFolder.DisplayName.Right(8) = ".numbers" AND theFolder.isBundleMBS Then
          if MyDictionary.HasKey(theFolder.Name) Then
            resultsLB.AddRow (theFolder.Name, theFolder.NativePath)
          end if
        end if
      end if
    end if
  end if
end if

Make sure you’re setting the encoding of the strings you read from the file. theFolder.Name will be UTF8. If the names in the dictionary have a different encoding (or if you haven’t set one), they will not match.

I have checked the encoding of the strings in the dictionary and they report they are UTF8. Not sure how to check the encoding of the file.

Ok. I am struggling with this dictionary stuff. Can someone please post some code to help me understand this? I have read through the LR and tried multiple versions of the sample code, but I can’t get this to work.

What is your code that loads the values from the file?

This is the code that reads the list of files to place into the dictionary and when I do a break, I can see all the file names in the dictionary.

Dim Import_TXTFI  As FolderItem
Dim Import_TXTTIS As TextInputStream
Dim One_Line As String

Import_TXTFI = New FolderItem ("" + sourceFileTF.Text + "", FolderItem.PathTypeShell)
Import_TXTTIS = TextInputStream.Open(Import_TXTFI)

Dim lines() As String
Dim MyDictionary As New Xojo.Core.Dictionary

If Import_TXTFI <> Nil Then
  If Import_TXTFI.Exists Then
    Try
      // Load the data and place it into the TextArray (array), one line at a time…
      While Not Import_TXTTIS.EOF
        // Load one line at a time and set it into an array
        One_Line = Import_TXTTIS.ReadLine
        
        // Assign the loaded line into the array
        lines.Append One_Line
        MyDictionary.Value("FileName") = lines
        
      Wend
    End Try
  End If
End if

However, I can’t figure out how to use the values in the dictionary to compare against the running file listing to say if the file names match, load them into a listbox.

The main problem here is that you’re using both an array and a dictionary. Use one or the other. Dictionary was suggested as a replacement for the array, due to its Lookup method, which can be considerably faster than IndexOf on a long array.

Secondarily, you are not setting the encoding of the text as you read it in. Change

Import_TXTTIS = TextInputStream.Open(Import_TXTFI)

to

Import_TXTTIS = TextInputStream.Open(Import_TXTFI)
Import_TXTTIS.Encoding = Encodings.UTF8

Another possible issue is you are dim’ing lines() and myDictionary as local variables. As such, they will not be available to any of the rest of your code. Make them properties of the window or put them in a module.

Thanks to everyone who replied to my request for assistance. I still have been unable to get the array or dictionary comparison to my list of file names to work. If anyone has an example code / project that may help me figure this out, I would greatly appreciate it.

Well, I guess I just needed to take some time away from looking at this code, because I have now got my comparison working. Thanks again to all who provide insight to assist me.

Before this line:

Import_TXTTIS = TextInputStream.Open(Import_TXTFI)

put:

Import_TXTTIS.Encoding = Encodings.UTF8

Also, it will be good that you read http://documentation.xojo.com/index.php/TextInputStream, especially the part

   // Be aware that TextInputStream.Open could raise an exception

in the example