directory tree -> array

Bob Sneidar bobsneidar at iotecdigital.com
Mon Feb 3 12:19:28 EST 2020


I already wrote some functions to do this but sent them to Richard in a demo stack. Here is the code based on directoryListing, which I believe is in the MasterLibrary. I made a minor adjustment to it if I recall. DirectoryListing was returning duplicate paths for each unique folder for some reason. I modified it to only return one unique path for a given folder. 

Setting the arrayData of a tree widget to the returned value of directoryListingToArray() function will yield the results you want. 

function directoryListing whatFolder, c
   /*
   Example:
   put 1 into cNum
   if target = empty then
      answer folder "Pick a folder you want to walk:"
      put it into whatFolder
      set cursor to watch
      put directoryListing(whatFolder,cNum) into target
      exit to top
   end if
   if the controlKey is down and the optionKey is down then
      put empty into target
      exit to top
   end if
   if the controlKey is down and the commandKey is down then
      put word 2 of the clickline into tLine
      put line tLine of target into tLaunch
      launch document tLaunch
      exit to top
   end if
   if the controlKey is down then
      put word 2 of the clickline into tLine
      put line tLine of target into whatFolder
      set itemDel to "/"
      delete last item of whatFolder
      set cursor to watch
      put directoryListing(whatFolder,cNum) into target
      exit to top
   end if
   if the optionKey is down then
      set itemDel to "/"
      sort lines of target descending by last item of each
      exit to top
   end if
   if the commandKey is down then
      set itemDel to "/"
      sort lines of target ascending by last item of each
      exit to top
   end if
   put word 2 of the clickline into tLine
   put line tLine of target into whatFolder
   set cursor to watch
   put directoryListing(whatFolder,cNum) into target
   global firstPass
   if firstPass is empty then 
      put whatFolder & cr into R
      put false into firstPass
   end if
   */
   
   set the directory to whatFolder
   if c = 0 or the result is not empty then 
      -- delete variable firstPass
      return R
   end if
   
   put the files into tFileList
   sort tFileList
   replace cr with cr & whatFolder & "/" in tFileList
   put whatFolder & "/" & tFileList & cr after R
   put line 2 to -1 of the folders into tDirList
   sort tDirList
   repeat for each line L in tDirList
      put directoryListing((whatFolder & "/" & L),(c-1)) after R
   end repeat
   
   -- delete variable firstPass
   return R
end directoryListing

function directoryListingToArray pDirectoryList
   put line 1 of pDirectoryList into tRoot
   delete line 1 of pDirectoryList
   set the itemDelimiter to "/"
   put empty into aArrayData [tRoot]
   
   repeat for each line tPath in pDirectoryList
      replace tRoot with empty in tPath      
      put "["  & quote before tPath
      put quote & "]" after tPath
      replace "/" with quote & "]" & space & "[" & quote in tPath
      put "[" & quote & tRoot & quote & "] " before tPath
      put "put empty into aArrayData " & tPath into tCommand
      do tCommand
   end repeat
   
   return aArrayData
end directoryListingToArray

Bob S


> On Feb 1, 2020, at 13:16 , Dick Kriesel via use-livecode <use-livecode at lists.runrev.com> wrote:
> 
> 
>> On Jan 22, 2020, at 10:17 AM, Richard Gaskin via use-livecode <use-livecode at lists.runrev.com> wrote:
>> 
>> I stumbled across a code challenge for y'all, one that seems seductively simple but I don't think it is:
>> 
>> What is the simplest way to build an array that reflects the files and folders within a given folder?
>> 
>> There's a discussion about this here:
>> 
>> https://forums.livecode.com/viewtopic.php?f=7&t=33565
>> 
>> 
>> On Jan 22, 2020, at 10:26 AM, Richard Gaskin via use-livecode <use-livecode at lists.runrev.com> wrote:
> 
>> 
>> We have many handlers that deliver directory trees as lists, but arrays are a different beast.  Because the depth is both unknowable and varied, I can't think of a way to do this without resorting to "do".
> 
> 
> 
> Since that thread vanished last week, and hasn’t returned, I'm offering help here instead.
> 
> The list of full paths contains enough information to build an array representation of the directory tree.
> 
> <code>
> /**
> 
> Summary: Given a list of full paths, and given the partial path they share, build an array representing the directory structure
> 
> pPaths: a return-delimited list of full paths
> 
> pPath: the path that was used to generate the list of full paths
> 
> Returns (array): A array with a branch node for each folder and a leaf node for each file
> 
> Description: Eliminate pPath from every line of pPaths. Then insert each line into an array.
> 
> email subject "directory tree -> array"
> 
> forum topic "f=7&t=33565"
> 
> */
> 
> 
> function arrayFromPaths pPaths, pPath -- a list of full paths, and the path that was used to generate the list
> 
> local tPaths, tFile, tArray
> 
> set the itemDelimiter to "/"
> 
> 
> put char 2 to -1 of replaceText( cr & pPaths, cr & pPath & slash, cr ) into tPaths -- eliminate pPath from every full path
> 
> repeat for each line tPath in tPaths -- insert each file name into the array
> 
> put the last item of tPath into tFile
> 
> delete the last item of tPath
> 
> if tPath is empty then -- the file is in folder pPath
> 
> put "true" into tArray[ tFile ]
> 
> else -- the file is in a folder in folder pPath
> 
> split tPath by slash
> 
> put "true" into tArray[ tPath ][ tFile ]
> 
> end if
> 
> end repeat
> 
> 
> return tArray
> 
> end arrayFromPaths
> 
> 
> on mouseUp
> 
> local tPaths = "a/b/c,a/b/d/e,a/b/d/f" -- folder a/b contains file c and folder d, which contains files e and f
> 
> local tPath = "a/b" -- the shared partial path
> 
> replace comma with cr in tPaths
> 
> 
> get arrayFromPaths( tPaths, tPath )
> 
> 
> breakpoint
> 
> end mouseUp
> 
> 
> </code>
> 
> If the topic reappears soon, I’ll repost there because reading code is easier there.
> 
> By, the way, thanks to RG for the bug report on my earlier posting in the now-vanished thread.
> 
> — Dick
> 
> 
> 
> _______________________________________________
> use-livecode mailing list
> use-livecode at lists.runrev.com
> Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
> http://lists.runrev.com/mailman/listinfo/use-livecode



More information about the use-livecode mailing list