Hi Bob.

I have a couple of other suggestions (driven by my paranoia :-)

1. There is a problem with passing empty for 'whatfolder'

Currently, if you pass in an empty folder, it  returns very misleading results - the files in the current directory when the function is called, plus the folders at the top level, with their files and subfolders.

Depending on how you want to interpret that case, you could EITHER

a. add a line something like

if whatFolder is empty then put "." into whatFolder

to the start of 'directorylisting'

OR

b. change

set the directory to whatfolder

TO

set the directory to (whatfolder&"/")

before getting the files listing.


2. in directoryListingToArray

      replace tRoot with empty in tPath

Hmmm - that's not safe - the string tRoot *could* occur multiple times within the filename.

Since all lines should (must) begin with tRoot, you could simply delete the first N characters of each line.

Alex.

On 03/02/2020 17:19, Bob Sneidar via use-livecode wrote:
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@lists.runrev.com> wrote:


On Jan 22, 2020, at 10:17 AM, Richard Gaskin via use-livecode 
<use-livecode@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@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@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode
_______________________________________________
use-livecode mailing list
use-livecode@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode

_______________________________________________
use-livecode mailing list
use-livecode@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode

Reply via email to