Android Question Group filetypes

ST500

Active Member
Licensed User
Hi All,

how can I Group the filetypes? For example you have a lot of pdf and jpeg files in a directory. I would like to group the filetypes and show they in list.
Thanks a lot.

ST500
 

Brian Dean

Well-Known Member
Licensed User
Longtime User
This will work providing you have good control of the filenames ...

B4X:
Sub sortFilenamesByType(filenames As List)
    Dim sortlist As List                          ' Temporary worklist
    sortlist.Initialize
    For Each name As String In filenames
        sortlist.Add(name.SubString(name.IndexOf(".")) & name)       
    Next
    sortlist.Sort(True)
    filenames.Clear
    For Each name As String In sortlist
        filenames.Add(name.SubString(4))       
    Next
End Sub

This copies the file extension to the front of the filename in a worklist, sorts the worklist, then replaces the filenames into the old list. Only works if every file has a three-character extension.
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
Hi All,

how can I Group the filetypes? For example you have a lot of pdf and jpeg files in a directory. I would like to group the filetypes and show they in list.
Thanks a lot.

ST500

This is different approach. Length of the extension doesn't matter.

B4X:
Sub ListFiles(strStartFolder As String, _
arrStrFilter() As String) As List

Dim i As Int
Dim n As Int
Dim iUBFilters As Int
Dim lstFiles As List
Dim lstFiles2 As List
Dim lstFiles3 As List
Dim lstExtensions As List
Dim arrIndexes() As Int
Dim strFile As String
Dim strExtension As String

iUBFilters = arrStrFilter.Length - 1

lstFiles.Initialize

lstFiles = File.ListFiles(strStartFolder)

If lstFiles.IsInitialized = False Then
Return lstFiles3 'return uninitialized list
End If

lstFiles2.Initialize
lstFiles3.Initialize
 lstExtensions.Initialize
 If arrStrFilter.Length > 0 Then
For i = 0 To lstFiles.Size - 1
strFile = lstFiles.Get(i)
If File.IsDirectory(strStartFolder, strFile) = False Then
strExtension = strFile.SubString(strFile.LastIndexOf(".") + 1)
For n = 0 To iUBFilters
If strExtension = arrStrFilter(n) Then
lstFiles2.Add(strFile)
lstExtensions.Add(strExtension)
Exit
End If
Next
End If
Next
Else
For i = 0 To lstFiles.Size - 1
strFile = lstFiles.Get(i)
If File.IsDirectory(strStartFolder, strFile) = False Then
strExtension = strFile.SubString(strFile.LastIndexOf(".") + 1)
lstFiles2.Add(strFile)
lstExtensions.Add(strExtension)
End If
Next
End If

arrIndexes = cSorting.SortOMStringListIDX(lstExtensions, True, False, -1, -1)

For i = 0 To arrIndexes.Length - 1
lstFiles3.Add(lstFiles2.Get(arrIndexes(i)))
Next

Return lstFiles3

End Sub
Sub SortOMStringListIDX(oList As List, bAscending As Boolean, bCaseInsensitive As Boolean, iStart As Int, iEnd As Int) As Int()
 Dim i As Long
Dim c As Long
Dim n As Long
Dim B4XOM As B4XOrderedMap
Dim arrString(oList.Size) As String

If iStart = -1 Then
iStart = 0
End If

If iEnd = -1 Then
iEnd = oList.Size - 1
 End If
 For i = iStart To iEnd
arrString(i) = oList.Get(i)
Next

If bCaseInsensitive Then
For i = iStart To iEnd
arrString(i) = arrString(i).ToLowerCase
Next
End If

If Check1DStringAllSame(arrString, False, iStart, iEnd) Then
Dim arrIndex2(1) As Int
arrIndex2(0) = -1 'telling the calling Sub that all items were same, so need for any sort
Return arrIndex2
End If

 B4XOM.Initialize
 For i = iStart To iEnd
Dim lstIndexes As List
If B4XOM.ContainsKey(arrString(i)) Then
lstIndexes = B4XOM.Get(arrString(i))
Else
lstIndexes.Initialize
End If
lstIndexes.Add(i)
B4XOM.Put(arrString(i), lstIndexes)
Next

B4XOM.Keys.Sort(bAscending)

Dim arrIndex((iEnd - iStart) + 1) As Int

For Each oValue As Object In B4XOM.Values
lstIndexes = oValue
For c = 0 To lstIndexes.Size - 1
arrIndex(n) = lstIndexes.Get(c)
n = n + 1
Next
Next

Return arrIndex

End Sub
Sub Check1DStringAllSame(arrstring() As String, bCaseInsensitive As Boolean, iStart As Int, iEnd As Int) As Boolean

Dim i As Int
Dim str As String

If arrstring.Length = 1 Then
Return True
End If

If iStart = -1 Then
iStart = 1
End If

If iEnd = -1 Then
iEnd = arrstring.Length - 1
End If

If bCaseInsensitive Then
str = arrstring(0).ToLowerCase
For i = iStart To iEnd
If arrstring(i).ToLowerCase.CompareTo(str) <> 0 Then
Return False
End If
Next
Else
str = arrstring(0)
For i = iStart To iEnd
If arrstring(i).CompareTo(str) <> 0 Then
Return False
End If
Next
End If

Return True

End Sub


RBS
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
This is different approach. Length of the extension doesn't matter.

B4X:
Sub ListFiles(strStartFolder As String, _
arrStrFilter() As String) As List

Dim i As Int
Dim n As Int
Dim iUBFilters As Int
Dim lstFiles As List
Dim lstFiles2 As List
Dim lstFiles3 As List
Dim lstExtensions As List
Dim arrIndexes() As Int
Dim strFile As String
Dim strExtension As String

iUBFilters = arrStrFilter.Length - 1

lstFiles.Initialize

lstFiles = File.ListFiles(strStartFolder)

If lstFiles.IsInitialized = False Then
Return lstFiles3 'return uninitialized list
End If

lstFiles2.Initialize
lstFiles3.Initialize
lstExtensions.Initialize
If arrStrFilter.Length > 0 Then
For i = 0 To lstFiles.Size - 1
strFile = lstFiles.Get(i)
If File.IsDirectory(strStartFolder, strFile) = False Then
strExtension = strFile.SubString(strFile.LastIndexOf(".") + 1)
For n = 0 To iUBFilters
If strExtension = arrStrFilter(n) Then
lstFiles2.Add(strFile)
lstExtensions.Add(strExtension)
Exit
End If
Next
End If
Next
Else
For i = 0 To lstFiles.Size - 1
strFile = lstFiles.Get(i)
If File.IsDirectory(strStartFolder, strFile) = False Then
strExtension = strFile.SubString(strFile.LastIndexOf(".") + 1)
lstFiles2.Add(strFile)
lstExtensions.Add(strExtension)
End If
Next
End If

arrIndexes = cSorting.SortOMStringListIDX(lstExtensions, True, False, -1, -1)

For i = 0 To arrIndexes.Length - 1
lstFiles3.Add(lstFiles2.Get(arrIndexes(i)))
Next

Return lstFiles3

End Sub
Sub SortOMStringListIDX(oList As List, bAscending As Boolean, bCaseInsensitive As Boolean, iStart As Int, iEnd As Int) As Int()
Dim i As Long
Dim c As Long
Dim n As Long
Dim B4XOM As B4XOrderedMap
Dim arrString(oList.Size) As String

If iStart = -1 Then
iStart = 0
End If

If iEnd = -1 Then
iEnd = oList.Size - 1
End If
For i = iStart To iEnd
arrString(i) = oList.Get(i)
Next

If bCaseInsensitive Then
For i = iStart To iEnd
arrString(i) = arrString(i).ToLowerCase
Next
End If

If Check1DStringAllSame(arrString, False, iStart, iEnd) Then
Dim arrIndex2(1) As Int
arrIndex2(0) = -1 'telling the calling Sub that all items were same, so need for any sort
Return arrIndex2
End If

B4XOM.Initialize
For i = iStart To iEnd
Dim lstIndexes As List
If B4XOM.ContainsKey(arrString(i)) Then
lstIndexes = B4XOM.Get(arrString(i))
Else
lstIndexes.Initialize
End If
lstIndexes.Add(i)
B4XOM.Put(arrString(i), lstIndexes)
Next

B4XOM.Keys.Sort(bAscending)

Dim arrIndex((iEnd - iStart) + 1) As Int

For Each oValue As Object In B4XOM.Values
lstIndexes = oValue
For c = 0 To lstIndexes.Size - 1
arrIndex(n) = lstIndexes.Get(c)
n = n + 1
Next
Next

Return arrIndex

End Sub
Sub Check1DStringAllSame(arrstring() As String, bCaseInsensitive As Boolean, iStart As Int, iEnd As Int) As Boolean

Dim i As Int
Dim str As String

If arrstring.Length = 1 Then
Return True
End If

If iStart = -1 Then
iStart = 1
End If

If iEnd = -1 Then
iEnd = arrstring.Length - 1
End If

If bCaseInsensitive Then
str = arrstring(0).ToLowerCase
For i = iStart To iEnd
If arrstring(i).ToLowerCase.CompareTo(str) <> 0 Then
Return False
End If
Next
Else
str = arrstring(0)
For i = iStart To iEnd
If arrstring(i).CompareTo(str) <> 0 Then
Return False
End If
Next
End If

Return True

End Sub


RBS

This:
arrIndexes = cSorting.SortOMStringListIDX(lstExtensions, True, False, -1, -1)
Should be:
arrIndexes = SortOMStringListIDX(lstExtensions, True, False, -1, -1)

as I had taken the sort routine out of the class.

RBS
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
how can I Group the filetypes? For example you have a lot of pdf and jpeg files in a directory. I would like to group the filetypes and show they in list.

This is a B4J Code but it should work in b4a/b4i as well

B4X:
    Dim path As String = "E:\B4XAdditionallibs\B4A"
    Dim files As List = File.ListFiles(path)
    Dim fm As Map
    fm.Initialize
    If files.IsInitialized And files.Size > 0 Then
        For i = 0 To files.Size-1
            Dim filename As String = files.Get(i)
            Dim ext As String = GetFileExt(filename)
            Dim l1 As List
            If fm.ContainsKey(ext) Then
                l1 = fm.Get(ext)
            Else
                l1.Initialize
                fm.Put(ext, l1)
            End If
            l1.Add(filename)
        Next
    End If
  
    For Each ext As String In fm.Keys
        Log($"========== Extension: ${ext} ========================="$)
        Dim flist As List = fm.Get(ext)
        For i = 0 To flist.Size-1
            Dim filename As String = flist.Get(i)
            Log($"${filename}"$)
        Next     
    Next

and

B4X:
Sub GetFileExt(FullPath As String) As String
    Return FullPath.SubString(FullPath.LastIndexOf(".")+1)
End Sub

This code does not care about the length of the extension.
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
I would use a type like this (again B4j code, but should work on others):

B4X:
#Region Project Attributes
    #MainFormWidth: 600
    #MainFormHeight: 600
#End Region

Sub Process_Globals
    Private fx As JFX
    Private MainForm As Form
    Type FileType(Name As String, Extn As String)
End Sub

Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    'MainForm.RootPane.LoadLayout("Layout1") 'Load the layout file.
    MainForm.Show
  
    Dim FileList As List
    FileList.Initialize
  
    Dim L As List = File.ListFiles("D:\") 'or whichever folder you want to sort
  
    For Each S As String In L
        Dim T As FileType
        T.Initialize
      
        If S.Contains(".") Then
            Dim Pos As Int = S.LastIndexOf(".")
            T.Name = S
            T.Extn = S.SubString(Pos + 1)
        Else
            T.Name = S
        End If
        FileList.Add(T)
    Next
  
    FileList.SortTypeCaseInsensitive("Extn",True)
  
    For Each T As FileType In FileList
        Log(T.Name)
    Next
  
  
End Sub

'Return true to allow the default exceptions handler to handle the uncaught exception.
Sub Application_Error (Error As Exception, StackTrace As String) As Boolean
    Return True
End Sub
 
Upvote 0

Mahares

Expert
Licensed User
Longtime User
@DonManfred code works well in B4A also. The only thing I would add if you want the files to be not only grouped by extension, but also sorted by name is to add this line:
B4X:
flist.SortCaseInsensitive(True)   'to sort the files by name,
below this line: Dim flist As List = fm.Get(ext)

I also tested @stevel05 code in B4A and it works well. The files are grouped and sorted by extension
 
Last edited:
Upvote 0

ST500

Active Member
Licensed User
Hi all,

thanks a lot for your help. You are the best.
I will test it all. At the moment I didn‘t have time for it, sorry?
 
Upvote 0
Top