james3mg Posted December 5, 2007 Share Posted December 5, 2007 Hey everyone - I've got a script that uses _FileListToArray() to write in all the file names I want (it's a list of pictures...file names like image1.jpg, image 2.jpg, image 100.jpg, etc). I'd like to sort them so that they are arranged in logical order (like Explorer does): image1.jpg image2.jpg image100.jpg _ArraySort() seems the logical way to do this, but the problem is that the order comes out like: image1.jpg image100.jpg image2.jpg because the numbers aren't read together as a single number, but rather as individual number characters, so everything with "1" after "image" will be grouped together before anything with a "2" after "image". Interestingly, I thought maybe grabbing output from a CMD window would be good enough, but CMD sorts numbers 'per character' rather than as a single number too! Seems only Explorer is smart enough to sort the way I'd like. The only way I can think of to make my own sorting function would be to use RegExp to find anywhere there are multiple numbers adjacent to each other, then pad all those places in the whole list with enough zeros that the numbers would get sorted correctly, then go through and use RegExpReplace to get rid of the extra zeros again. This process sounds quite error-prone to me, but I can't come up with anything better. Any code wizards out there come up with a better method for pulling this off that they could share, or at least some insights as to how they'd go about doing it so I can give it a shot myself? Thanks :-D "There are 10 types of people in this world - those who can read binary, and those who can't.""We've heard that a million monkeys at a million keyboards could produce the complete works of Shakespeare; now, thanks to the Internet, we know that is not true." ~Robert Wilensky0101101 1001010 1100001 1101101 1100101 1110011 0110011 1001101 10001110000101 0000111 0001000 0001110 0001101 0010010 1010110 0100001 1101110 Link to comment Share on other sites More sharing options...
randallc Posted December 5, 2007 Share Posted December 5, 2007 (edited) Hi,I think vbs sorts the way you want; try the sort in "Array2D.au3" [link in sig] UDF Fieldsort to check [which is vbs with subsort]I don't have time right now.Best, randallNo vbs does not, sorry Edited December 5, 2007 by randallc ExcelCOM... AccessCom.. Word2... FileListToArrayNew...SearchMiner... Regexps...SQL...Explorer...Array2D.. _GUIListView...array problem...APITailRW Link to comment Share on other sites More sharing options...
james3mg Posted December 5, 2007 Author Share Posted December 5, 2007 (edited) Hi, I think vbs sorts the way you want; try the sort in "Array2D.au3" [link in sig] UDF Fieldsort to check [which is vbs with subsort] I don't have time right now. Best, randallThanks for the suggestion - just saw your followup note: thanks for trying. Anyway, I tried it before I saw your note and got Array2d.au3 (418) : ==> The requested action with this object has failed.: $ar_Temp = $vbs.run ("Quick_SortColumn1", $ar_Temp, $i_Asc, $First, $Last, $i_ViewColNum) $ar_Temp = $vbs.run ("Quick_SortColumn1", $ar_Temp, $i_Asc, $First, $Last, $i_ViewColNum)^ ERRORYour functions look powerful - I'd like to play with them, but with errors like that I can't. Do I have to have VB studio installed or something? Anyway, I don't want to get off on a tangent - I'd still love someone's brainstorm on how to do this efficiently. (sp?) -Later Edited December 5, 2007 by james3mg "There are 10 types of people in this world - those who can read binary, and those who can't.""We've heard that a million monkeys at a million keyboards could produce the complete works of Shakespeare; now, thanks to the Internet, we know that is not true." ~Robert Wilensky0101101 1001010 1100001 1101101 1100101 1110011 0110011 1001101 10001110000101 0000111 0001000 0001110 0001101 0010010 1010110 0100001 1101110 Link to comment Share on other sites More sharing options...
weaponx Posted December 5, 2007 Share Posted December 5, 2007 (edited) I've got your back. All I need to know is, do all the filenames begin with "image"??? If so, here is the solution: #include <array.au3> Dim $array[4] = ["image1.jpg", "image100.jpg", "image2.jpg", "image200.jpg"] _ArrayDisplay($array) _ArrayLogicalSort($array, "image") _ArrayDisplay($array) Func _ArrayLogicalSort(ByRef $theArray, $leadingString) For $X = 0 to Ubound($theArray) - 1 For $Y = $X to Ubound($theArray) - 1 If Number(StringTrimLeft(StringTrimRight($theArray[$Y], 4), StringLen($leadingString))) < Number(StringTrimLeft(StringTrimRight($theArray[$X], 4), StringLen($leadingString))) Then $temp = $theArray[$Y] $theArray[$Y] = $theArray[$X] $theArray[$X] = $temp EndIf Next Next EndFunc Edited December 5, 2007 by weaponx Link to comment Share on other sites More sharing options...
Richard Robertson Posted December 5, 2007 Share Posted December 5, 2007 Explorer will sort by reading the whole number only if you have NT 4 or above, and have the option not disabled. There's a switch somewhere in the registry that controls it. Link to comment Share on other sites More sharing options...
randallc Posted December 6, 2007 Share Posted December 6, 2007 Your functions look powerful - I'd like to play with them, but with errors like that I can't. Do I have to have VB studio installed or something?Hi, OK If you want to see it working, go to link with "SearchMiner"; that fast sorts LV by column on subsorts via vbs routine. Not sure why you got your error; maybe show the script... you need WinXP or better, I think, for the "Scripting Object" to be installed. [i have made workarounds to just use vbs scripts on Win 98, without Scripting Object; then Win98 just needs vbs5 installed] best, randall ExcelCOM... AccessCom.. Word2... FileListToArrayNew...SearchMiner... Regexps...SQL...Explorer...Array2D.. _GUIListView...array problem...APITailRW Link to comment Share on other sites More sharing options...
randallc Posted December 6, 2007 Share Posted December 6, 2007 (edited) Hi,Or go to "Array2D" in link in signature now, [current AutoIt version 3.2.10.0]or, zip file for working example;Array2D10Best, Randall Edited December 6, 2007 by randallc ExcelCOM... AccessCom.. Word2... FileListToArrayNew...SearchMiner... Regexps...SQL...Explorer...Array2D.. _GUIListView...array problem...APITailRW Link to comment Share on other sites More sharing options...
james3mg Posted December 6, 2007 Author Share Posted December 6, 2007 (edited) I've got your back. All I need to know is, do all the filenames begin with "image"??? If so, here is the solution: #include <array.au3> Dim $array[4] = ["image1.jpg", "image100.jpg", "image2.jpg", "image200.jpg"] _ArrayDisplay($array) _ArrayLogicalSort($array, "image") _ArrayDisplay($array) Func _ArrayLogicalSort(ByRef $theArray, $leadingString) For $X = 0 to Ubound($theArray) - 1 For $Y = $X to Ubound($theArray) - 1 If Number(StringTrimLeft(StringTrimRight($theArray[$Y], 4), StringLen($leadingString))) < Number(StringTrimLeft(StringTrimRight($theArray[$X], 4), StringLen($leadingString))) Then $temp = $theArray[$Y] $theArray[$Y] = $theArray[$X] $theArray[$X] = $temp EndIf Next Next EndFuncWow...that's a lot less 'shuffling' numbers around than I'd have been able to get it done in! Unfortunately to your question...no. I was just using that as an example. I'd like to come up with a way that the function can sort ANY list, and if there are multi-digit numbers in the list, sort them 'logically' rather than alphanum. But your example may help me get started, thanks! ...now I've got to get my head back around regexps again. Edited December 6, 2007 by james3mg "There are 10 types of people in this world - those who can read binary, and those who can't.""We've heard that a million monkeys at a million keyboards could produce the complete works of Shakespeare; now, thanks to the Internet, we know that is not true." ~Robert Wilensky0101101 1001010 1100001 1101101 1100101 1110011 0110011 1001101 10001110000101 0000111 0001000 0001110 0001101 0010010 1010110 0100001 1101110 Link to comment Share on other sites More sharing options...
weaponx Posted December 6, 2007 Share Posted December 6, 2007 (edited) Wow...that's a lot less 'shuffling' numbers around than I'd have been able to get it done in! Unfortunately to your question...no. I was just using that as an example. I'd like to come up with a way that the function can sort ANY list, and if there are multi-digit numbers in the list, sort them 'logically' rather than alphanum. But your example may help me get started, thanks! ...now I've got to get my head back around regexps again. I'm perplexed as to how Microsloth does the sorting. I'm guessing each individual character is compared and if one happens to be a digit, it ....dear god i've gone crosseyed. Here is another version that accepts files in this format %NON-NUMBERS%%NUMBERS% (without the % obviously), the numeric digits will be padded with zeroes for comparison. Still pretty far off from an all-encompassing solution. #include <array.au3> Dim $array[4] = ["image1.jpg", "image100.jpg", "image2.jpg", "image200.jpg"] _ArrayDisplay($array) _ArrayLogicalSort2($array) _ArrayDisplay($array) Func _ArrayLogicalSort2(ByRef $theArray) $padLength = 0 ;Determine pad length For $X = 0 to Ubound($theArray) - 1 ;[0] = Leading non-numeric [1] = trailing numeric $fileNameArray = StringRegExp($theArray[$X], "(\D*)(\d*)\.", 1) If NOT @ERROR Then $currLength = StringLen($fileNameArray[1]) If $currLength > $padLength Then $padLength = $currLength EndIf Next ;Sort by padding trailing digits For $X = 0 to Ubound($theArray) - 1 $tempArrayX = StringRegExp($theArray[$X], "(\D*)(\d*)\.", 1) If NOT @ERROR Then For $Y = $X to Ubound($theArray) - 1 $tempArrayY = StringRegExp($theArray[$Y], "(\D*)(\d*)\.", 1) If Number(StringFormat("%0" & $padLength & "d", $tempArrayY[1])) < Number(StringFormat("%0" & $padLength & "d", $tempArrayX[1])) Then $temp = $theArray[$Y] $theArray[$Y] = $theArray[$X] $theArray[$X] = $temp EndIf Next EndIf Next EndFunc Edited December 6, 2007 by weaponx Link to comment Share on other sites More sharing options...
james3mg Posted December 17, 2007 Author Share Posted December 17, 2007 I've finally written a function that will do this; go to this topic for the UDF.Later! "There are 10 types of people in this world - those who can read binary, and those who can't.""We've heard that a million monkeys at a million keyboards could produce the complete works of Shakespeare; now, thanks to the Internet, we know that is not true." ~Robert Wilensky0101101 1001010 1100001 1101101 1100101 1110011 0110011 1001101 10001110000101 0000111 0001000 0001110 0001101 0010010 1010110 0100001 1101110 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now