Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

Simple sorting

 [1/8] from: sjohnson::cornerstonepaymentsystems::com at: 25-Sep-2002 17:19


Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Hi all, Been off the list for a while because I just couldn't keep up with the volume of this great living list! Quickie question: How do I get the code, listing: sort read %., to sort alphabetically by directories first then by filenames? So, the result looks like this:
>> sort read %.
== [%dir1/ %dir2/ %dir3/ %file1 %file2 %file3] I know I'm missing something easy here...maybe a sort option? Regards, Sean C. Johnson -- Binary/unsupported file stripped by Listar -- -- Type: image/jpeg -- File: image001.jpg -- Desc: image001.jpg

 [2/8] from: greggirwin:mindspring at: 25-Sep-2002 16:02


Hi Sean, << How do I get the code, listing: sort read %., to sort alphabetically by directories first then by filenames? So, the result looks like this: [%dir1/ %dir2/ %dir3/ %file1 %file2 %file3] >> I don't know that there's a single switch to do something like that. Maybe someone else knows a nifty trick I don't. In any case, I whipped this up real quick to show how you *could* do it. It uses a function I have to split blocks into sub-blocks based on predicates. dir-file-sort: func [ {Returns the block of files with directories first, followed by files, with each group sorted.} block [any-block!] /local result ][ result: copy [] foreach blk split block [:dir?] none [ append result sort blk ] ] split: func [ {Applies each predicate to each element in blk and returns a block of blocks with items partitioned by which predicate they match. If an item doesn't match any predicate, it will be in the last block. Only handles simple args right now.} series [series!] predicates [block!] args /local match result p ][ result: copy [] loop add length? predicates 1 [append/only result copy []] repeat el series [ match: false repeat i length? predicates [ ; Have to use a temp var for the predicate here, in addition to ; the result of the predicate call. p: get predicates/:i match: p :el either block? args [args/:i][args] if match [ append result/:i :el break ] ] if not match [ append last result :el ] ] result ] ;split [1 2 3.4 5.6 7 8.9] [integer? decimal?] none ;split [1 2 3.4 5.6 7 8.9 0 100] [lesser? greater?] [3 7] ;split [1 2 3.4 5.6 7 8.9 0 100] [lesser? greater?] 3 I only tested this briefly but it should give you a starting point if nothing else. BIG CAVEAT: DIR? needs full path info if you're working on a list of files that aren't in the current directory. HTH! --Gregg

 [3/8] from: carl:cybercraft at: 26-Sep-2002 12:42


On 26-Sep-02, Sean Johnson wrote:
> Content-Type: text/plain; > charset="iso-8859-1"
<<quoted lines omitted: 10>>
> Regards, > Sean C. Johnson
Sort has a compare refinement that allows you to use a function to make a comparison, the idea being to return true or false depending on a comparison of two values. (I think - I only used it for the first time yesterday:) For instance, this sorts on strings from the second character onwards...
>> blk: ["xccc" "yaaa" "zbbb"]
== ["xccc" "yaaa" "zbbb"]
>> sort/compare blk func [a b][(second a) < second b]
== ["yaaa" "zbbb" "xccc"] So, expand on that to sort your directory. (My rushed attempt didn't work, so I won't inflict it on you;) Note, if you seperate your function, use... sort/compare blk :my-function Note the colon. -- Carl Read

 [4/8] from: al:bri:xtra at: 26-Sep-2002 13:51


Sean wrote:
> How do I get the code, listing: sort read %., to sort alphabetically by
directories first then by filenames? I'd use something like this: sort/compare probe read %/c/Rebol/ func [File1 [file!] File2 [file!]] [ if all [(#"/" = last File1) (#"/" <> last File2)] [return true] if all [(#"/" <> last File1) (#"/" = last File2)] [return false] File1 < File2 ] I'm almost sure that the sorting function could be improved. Andrew Martin ICQ: 26227169 http://valley.150m.com/

 [5/8] from: greggirwin:mindspring at: 26-Sep-2002 21:11


This is a resend. The original didn't seem to make it to the list. Hi Sean, << How do I get the code, listing: sort read %., to sort alphabetically by directories first then by filenames? So, the result looks like this: [%dir1/ %dir2/ %dir3/ %file1 %file2 %file3] >> I don't know that there's a single switch to do something like that. Maybe someone else knows a nifty trick I don't. In any case, I whipped this up real quick to show how you *could* do it. It uses a function I have to split blocks into sub-blocks based on predicates. dir-file-sort: func [ {Returns the block of files with directories first, followed by files, with each group sorted.} block [any-block!] /local result ][ result: copy [] foreach blk split block [:dir?] none [ append result sort blk ] ] split: func [ {Applies each predicate to each element in blk and returns a block of blocks with items partitioned by which predicate they match. If an item doesn't match any predicate, it will be in the last block. Only handles simple args right now.} series [series!] predicates [block!] args /local match result p ][ result: copy [] loop add length? predicates 1 [append/only result copy []] repeat el series [ match: false repeat i length? predicates [ ; Have to use a temp var for the predicate here, in addition to ; the result of the predicate call. p: get predicates/:i match: p :el either block? args [args/:i][args] if match [ append result/:i :el break ] ] if not match [ append last result :el ] ] result ] ;split [1 2 3.4 5.6 7 8.9] [integer? decimal?] none ;split [1 2 3.4 5.6 7 8.9 0 100] [lesser? greater?] [3 7] ;split [1 2 3.4 5.6 7 8.9 0 100] [lesser? greater?] 3 I only tested this briefly but it should give you a starting point if nothing else. BIG CAVEAT: DIR? needs full path info if you're working on a list of files that aren't in the current directory. HTH! --Gregg

 [6/8] from: anton:lexicon at: 27-Sep-2002 14:14


You could also do it like this, which does not use dir? and does not use any extra functions: dir: %./ ; current directory result: copy [] dirs: copy [] files: copy [] foreach file read dir [ append either #"/" = last file [dirs][files] file ] result: compose [(sort dirs) (sort files)] I have found it handy to have the files and dirs in separate blocks for other processing, so that may make this way preferable. Anton.

 [7/8] from: carl:cybercraft at: 27-Sep-2002 20:12


I was sure sort/compare could be used, so I tried again and came up with this... dir-sort: func [a b][ either any [ all [#"/" = last a #"/" = last b] all [#"/" <> last a #"/" <> last b] ][ a < b ][ #"/" = last a ; Change to b to place files first. ] ] ; To test... dir: %./ ; Current directory. result: sort/compare read dir :dir-sort It'll fall over if there's a file without any characters to its name, (is that likely to exist on any systems?), but otherwise it seems to work. Carl. On 27-Sep-02, Anton wrote:
> You could also do it like this, > which does not use dir? and does not
<<quoted lines omitted: 15>>
>> result looks like this: [%dir1/ %dir2/ %dir3/ %file1 %file2 %file3] >>>>
-- Carl Read

 [8/8] from: sjohnson:cornerstonepaymentsystems at: 27-Sep-2002 17:46


Thanks everybody for the suggestions! I popped Greg's two functions in my script and it worked first time out. The others I have kept to study a bit. :) --- Sean

Notes
  • Quoted lines have been omitted from some messages.
    View the message alone to see the lines that have been omitted