benners Posted January 22, 2013 Share Posted January 22, 2013 I have written a function that reads a specified table from an msi file. The function uses sql syntax to query the table and uses the "Order By" keyword to sort the results.Being Microsoft, things are sorted differently. The columns that are integer based sort as expected but the string columns don't sort. After wasting time trying different things I came across some info on MS siteThe ORDER BY clause is optional and causes an initial delay during sorting. Ordering by strings will group identical strings together, but it will not alphabetize the strings.WTF is the point in that I don't know but this leads me to my question.If the column is an integer I can let SQL sort it. If not I can sort the array by getting the column index of the specified column. Is there a way to check a string to see if it is a number or, (before StringIsInt is mentioned) a number in version format such as 1.0.0.0?.I am thinking of letting _ArraySort do all the sorting once I establish which column in the array is the one to sort but was looking for other solutions.I have attached the files with code and an msi.ThanksTest.7z Link to comment Share on other sites More sharing options...
LurchMan Posted January 22, 2013 Share Posted January 22, 2013 _ArraySort () will be your best option in my opinion. Dating a girl is just like writing software. Everything's going to work just fine in the testing lab (dating), but as soon as you have contract with a customer (marriage), then your program (life) is going to be facing new situations you never expected. You'll be forced to patch the code (admit you're wrong) and then the code (wife) will just end up all bloated and unmaintainable in the end. Link to comment Share on other sites More sharing options...
benners Posted January 23, 2013 Author Share Posted January 23, 2013 _ArraySort () will be your best option in my opinion. That's another problem, >_< . The SQL will sort the integer columns, ascending order but not alphabetize the string column. The _ArraySort will alphabetize the strings column, but the integer columns are just added as strings so get sorted as them i.e 1 11 100 2 20 3 30 etc. I shall have to try and use StringRegExpReplace and StringIsInt to check the string and sort with the best method. I'll check the string like StringIsInt(StringRegExpReplace('0x400', '\D', '')) this should return 1 for number strings and 0 for actual strings Cheers Link to comment Share on other sites More sharing options...
MilesAhead Posted January 23, 2013 Share Posted January 23, 2013 I did a modification of _ArraySort that allows you to pass in the sorting function of your own design. See the It's along the lines of C Qsort where you passed in a pointer to the sort function. Only in AutoIt you pass in the string that's the function name for use by Call(). My Freeware Page Link to comment Share on other sites More sharing options...
czardas Posted January 23, 2013 Share Posted January 23, 2013 I'm not quite sure what the problem is here. #include <Array.au3> Global $aArray[7] = ["1","11","100","2","20","3","30"] ; Array Contains strings _ArraySort($aArray) ; Sort strings _ArrayDisplay($aArray, "Alphanumeric") For $i = 0 To 6 ; Convert all string values to numbers $aArray[$i] = Number($aArray[$i]) Next _ArraySort($aArray) ; Sort Numbers _ArrayDisplay($aArray, "Numeric Sorting") kylomas 1 operator64Â Â ArrayWorkshop Link to comment Share on other sites More sharing options...
kylomas Posted January 23, 2013 Share Posted January 23, 2013 czardas, Thank You, this solves a prob thats been bugging me for some time. K.I.S.S. is the order of the day! kylomas Forum Rules        Procedure for posting code "I like pigs. Dogs look up to us. Cats look down on us. Pigs treat us as equals." - Sir Winston Churchill Link to comment Share on other sites More sharing options...
MilesAhead Posted January 23, 2013 Share Posted January 23, 2013 (edited) I'm not quite sure what the problem is here. #include <Array.au3> Global $aArray[7] = ["1","11","100","2","20","3","30"] ; Array Contains strings _ArraySort($aArray) ; Sort strings _ArrayDisplay($aArray, "Alphanumeric") For $i = 0 To 6 ; Convert all string values to numbers $aArray[$i] = Number($aArray[$i]) Next _ArraySort($aArray) ; Sort Numbers _ArrayDisplay($aArray, "Numeric Sorting") Conversion to number works in the above format. But strings in typical file version format such as 1.0.0.0 you would have to traverse the array doing some conversion. With a custom comparison function the orginal data is not changed. It's just compared by a function that knows which of the two values is greater, less than, or equal. It's hardly revolutionary. C standard library came out what, in the late 80s or early 90s? Edited January 23, 2013 by MilesAhead My Freeware Page Link to comment Share on other sites More sharing options...
czardas Posted January 24, 2013 Share Posted January 24, 2013 (edited) Conversion to number works in the above format. But strings in typical file version format such as 1.0.0.0 you would have to traverse the array doing some conversion. How true! expandcollapse popup#include <Array.au3> _Test() Func _Test() Local $aArray[4] = ["12.5.3.09","7.34.45.1","7.2.0.0","12.5.0.143"] _ArrayDisplay($aArray, "Before") _VersionSort($aArray) _ArrayDisplay($aArray, "After") EndFunc Func _VersionSort(ByRef $aVersions, $iStart = 0) If Not IsArray($aVersions) Or UBound($aVersions, 0) > 1 Then Return SetError(1) ; Not a 1D array. If Not IsInt($iStart) Then Return SetError(2) ; This parameter needs to be an integer. Local $iEnd = UBound($aVersions) -1 If $iStart < 0 Or $iStart > $iEnd Then Return SetError(3) ; Start parameters out of range. Local $aSplit, $iDelimiters = 0 For $i = 1 To StringLen($aVersions[$iStart]) If StringMid($aVersions[$iStart], $i, 1) = "." Then $iDelimiters += 1 Next For $i = $iStart To $iEnd $aSplit = StringSplit($aVersions[$i], ".") If $iDelimiters <> $aSplit[0] -1 Then Return SetError(4) ; Inconsistant version format. $aVersions[$i] = "" For $j = 1 To $aSplit[0] If StringLen($aSplit[$j]) > 5 Then Return SetError(5) ; Max five figures between dots $aVersions[$i] &= StringFormat("%05d", $aSplit[$j]) Next Next _ArraySort($aVersions) For $i = $iStart To $iEnd $aSplit = _StringEqualSplit($aVersions[$i], 5) $aVersions[$i] = "" For $j = 0 To $iDelimiters -1 $aVersions[$i] &= Number($aSplit[$j]) & "." Next $aVersions[$i] &= Number($aSplit[$j]) Next EndFunc Func _StringEqualSplit($sString, $iNumChars) If Not IsString($sString) Or $sString = "" Then Return SetError(1, 0, 0) If Not IsInt($iNumChars) Or $iNumChars < 1 Then Return SetError(2, 0, 0) Return StringRegExp($sString, "(?s).{1," & $iNumChars & "}", 3) EndFunc Works for up to 5 digits between dots. version xxxxx.xxxxx.xxxxx.xxxxx.xxxxx.xxxxx etc... It's only working on a 1D array ATM, but that can easily be changed. Edit: Minor Adjustments Edited January 24, 2013 by czardas operator64Â Â ArrayWorkshop Link to comment Share on other sites More sharing options...
MilesAhead Posted January 24, 2013 Share Posted January 24, 2013 How true! I think you miss the point. With your method you have to traverse the array, transform all the values, sort, then once you have the order, traverse again the return the contents to the original values if the source data needs to be preserved. With a custom compare function, you don't alter the orignal data. Only load local variales in the compare function. I don't understand why I have to arge stuff that's in every computer science textbook. Notice I still have the orginal array contents. Only the order of elements has changed. expandcollapse popupDim $testArray[8] = ["2.54.0.2", "1.0.0.0", "7.25.11.4", "2.1.0.0", "3.4.15.1", "1.1.0.0", "7.7.7.7", "4.4.4.4"] $msg = "" For $x = 0 To 7 $msg &= $testArray[$x] & @CRLF Next MsgBox(0x1040, "Test", $msg) _ArraySort($testArray, 0, 0, 0, 0, "CustomCompare") $msg = "" For $x = 0 To 7 $msg &= $testArray[$x] & @CRLF Next MsgBox(0x1040, "Test", $msg) Func CustomCompare($left, $right) Local $l = StringSplit($left, ".") Local $r = StringSplit($right, ".") For $x = 1 To 4 $l[$x] = Int($l[$x]) $r[$x] = Int($r[$x]) Next For $x = 1 To 4 If $l[$x] < $r[$x] Then Return -1 ElseIf $l[$x] = $r[$x] Then ContinueLoop Else Return 1 EndIf Next EndFunc ;==>CustomCompare ; #FUNCTION# ==================================================================================================================== ; Name...........: _ArraySort ; Description ...: Sort a 1D or 2D array on a specific index using the quicksort/insertionsort algorithms. ; Syntax.........: _ArraySort(ByRef $avArray[, $iDescending = 0[, $iStart = 0[, $iEnd = 0[, $iSubItem = 0]]]]) ; Parameters ....: $avArray - Array to sort ; $iDescending - [optional] If set to 1, sort descendingly ; $iStart - [optional] Index of array to start sorting at ; $iEnd - [optional] Index of array to stop sorting at ; $iSubItem - [optional] Sub-index to sort on in 2D arrays ; Return values .: Success - 1 ; Failure - 0, sets @error: ; |1 - $avArray is not an array ; |2 - $iStart is greater than $iEnd ; |3 - $iSubItem is greater than subitem count ; |4 - $avArray has too many dimensions ; Author ........: Jos van der Zande <jdeb at autoitscript dot com> ; Modified.......: LazyCoder - added $iSubItem option, Tylo - implemented stable QuickSort algo, ; Modified.......: Jos van der Zande - changed logic to correctly Sort arrays with mixed Values and Strings, ; Modified.......: Ultima - major optimization, code cleanup, removed $i_Dim parameter ; Modified.......: MilesAhead - added user defined $iCompare for generalized qsort() ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: Yes ; =============================================================================================================================== Func _ArraySort(ByRef $avArray, $iDescending = 0, $iStart = 0, $iEnd = 0, $iSubItem = 0, $iCompare = "") If Not IsArray($avArray) Then Return SetError(1, 0, 0) Local $iUBound = UBound($avArray) - 1 ; Bounds checking If $iEnd < 1 Or $iEnd > $iUBound Then $iEnd = $iUBound If $iStart < 0 Then $iStart = 0 If $iStart > $iEnd Then Return SetError(2, 0, 0) ; Sort Switch UBound($avArray, 0) Case 1 __ArrayQuickSort1D($avArray, $iStart, $iEnd, $iCompare) If $iDescending Then _ArrayReverse($avArray, $iStart, $iEnd) Case 2 Local $iSubMax = UBound($avArray, 2) - 1 If $iSubItem > $iSubMax Then Return SetError(3, 0, 0) If $iDescending Then $iDescending = -1 Else $iDescending = 1 EndIf __ArrayQuickSort2D($avArray, $iDescending, $iStart, $iEnd, $iSubItem, $iSubMax, $iCompare) Case Else Return SetError(4, 0, 0) EndSwitch Return 1 EndFunc ;==>_ArraySort ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name...........: __ArrayQuickSort1D ; Description ...: Helper function for sorting 1D arrays ; Syntax.........: __ArrayQuickSort1D(ByRef $avArray, ByRef $iStart, ByRef $iEnd) ; Parameters ....: $avArray - Array to sort ; $iStart - Index of array to start sorting at ; $iEnd - Index of array to stop sorting at ; Return values .: None ; Author ........: Jos van der Zande, LazyCoder, Tylo, Ultima ; Modified.......: MilesAhead - added user defined $iCompare for generalized qsort() ; Remarks .......: For Internal Use Only ; Related .......: ; Link ..........: ; Example .......: ; =============================================================================================================================== Func __ArrayQuickSort1D(ByRef $avArray, ByRef $iStart, ByRef $iEnd, $iCompare = "") If $iEnd <= $iStart Then Return Local $vTmp ; InsertionSort (faster for smaller segments) If ($iEnd - $iStart) < 15 Then Local $vCur For $i = $iStart + 1 To $iEnd $vTmp = $avArray[$i] If $iCompare Then For $j = $i - 1 To $iStart Step -1 If (Call($iCompare, $vTmp, $avArray[$j]) >= 0) Then ExitLoop $avArray[$j + 1] = $avArray[$j] Next ElseIf IsNumber($vTmp) Then For $j = $i - 1 To $iStart Step -1 $vCur = $avArray[$j] ; If $vTmp >= $vCur Then ExitLoop If ($vTmp >= $vCur And IsNumber($vCur)) Or (Not IsNumber($vCur) And StringCompare($vTmp, $vCur) >= 0) Then ExitLoop $avArray[$j + 1] = $vCur Next Else For $j = $i - 1 To $iStart Step -1 If (StringCompare($vTmp, $avArray[$j]) >= 0) Then ExitLoop $avArray[$j + 1] = $avArray[$j] Next EndIf $avArray[$j + 1] = $vTmp Next Return EndIf ; QuickSort Local $l = $iStart, $r = $iEnd, $vPivot = $avArray[Int(($iStart + $iEnd) / 2)], $fNum = IsNumber($vPivot) Do If $iCompare Then While (Call($iCompare, $avArray[$l], $vPivot) < 0) $l += 1 WEnd ; While $avArray[$R] > $vPivot While (Call($iCompare, $avArray[$r], $vPivot) > 0) $r -= 1 WEnd ElseIf $fNum Then ; While $avArray[$L] < $vPivot While ($avArray[$l] < $vPivot And IsNumber($avArray[$l])) Or (Not IsNumber($avArray[$l]) And StringCompare($avArray[$l], $vPivot) < 0) $l += 1 WEnd ; While $avArray[$R] > $vPivot While ($avArray[$r] > $vPivot And IsNumber($avArray[$r])) Or (Not IsNumber($avArray[$r]) And StringCompare($avArray[$r], $vPivot) > 0) $r -= 1 WEnd Else While (StringCompare($avArray[$l], $vPivot) < 0) $l += 1 WEnd While (StringCompare($avArray[$r], $vPivot) > 0) $r -= 1 WEnd EndIf ; Swap If $l <= $r Then $vTmp = $avArray[$l] $avArray[$l] = $avArray[$r] $avArray[$r] = $vTmp $l += 1 $r -= 1 EndIf Until $l > $r __ArrayQuickSort1D($avArray, $iStart, $r, $iCompare) __ArrayQuickSort1D($avArray, $l, $iEnd, $iCompare) EndFunc ;==>__ArrayQuickSort1D ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name...........: __ArrayQuickSort2D ; Description ...: Helper function for sorting 2D arrays ; Syntax.........: __ArrayQuickSort2D(ByRef $avArray, ByRef $iStep, ByRef $iStart, ByRef $iEnd, ByRef $iSubItem, ByRef $iSubMax) ; Parameters ....: $avArray - Array to sort ; $iStep - Step size (should be 1 to sort ascending, -1 to sort descending!) ; $iStart - Index of array to start sorting at ; $iEnd - Index of array to stop sorting at ; $iSubItem - Sub-index to sort on in 2D arrays ; $iSubMax - Maximum sub-index that array has ; Return values .: None ; Author ........: Jos van der Zande, LazyCoder, Tylo, Ultima ; Modified.......: MilesAhead - added user defined $iCompare for generalized qsort() ; Remarks .......: For Internal Use Only ; Related .......: ; Link ..........: ; Example .......: ; =============================================================================================================================== Func __ArrayQuickSort2D(ByRef $avArray, ByRef $iStep, ByRef $iStart, ByRef $iEnd, ByRef $iSubItem, ByRef $iSubMax, $iCompare = "") If $iEnd <= $iStart Then Return ; QuickSort Local $vTmp, $l = $iStart, $r = $iEnd, $vPivot = $avArray[Int(($iStart + $iEnd) / 2)][$iSubItem], $fNum = IsNumber($vPivot) Do If $iCompare Then While (Call($iCompare, $avArray[$l][$iSubItem], $vPivot) < 0) $l += 1 WEnd While (Call($iCompare, $avArray[$r][$iSubItem], $vPivot) > 0) $r -= 1 WEnd ElseIf $fNum Then ; While $avArray[$L][$iSubItem] < $vPivot While ($iStep * ($avArray[$l][$iSubItem] - $vPivot) < 0 And IsNumber($avArray[$l][$iSubItem])) Or (Not IsNumber($avArray[$l][$iSubItem]) And $iStep * StringCompare($avArray[$l][$iSubItem], $vPivot) < 0) $l += 1 WEnd ; While $avArray[$R][$iSubItem] > $vPivot While ($iStep * ($avArray[$r][$iSubItem] - $vPivot) > 0 And IsNumber($avArray[$r][$iSubItem])) Or (Not IsNumber($avArray[$r][$iSubItem]) And $iStep * StringCompare($avArray[$r][$iSubItem], $vPivot) > 0) $r -= 1 WEnd Else While ($iStep * StringCompare($avArray[$l][$iSubItem], $vPivot) < 0) $l += 1 WEnd While ($iStep * StringCompare($avArray[$r][$iSubItem], $vPivot) > 0) $r -= 1 WEnd EndIf ; Swap If $l <= $r Then For $i = 0 To $iSubMax $vTmp = $avArray[$l][$i] $avArray[$l][$i] = $avArray[$r][$i] $avArray[$r][$i] = $vTmp Next $l += 1 $r -= 1 EndIf Until $l > $r __ArrayQuickSort2D($avArray, $iStep, $iStart, $r, $iSubItem, $iSubMax, $iCompare) __ArrayQuickSort2D($avArray, $iStep, $l, $iEnd, $iSubItem, $iSubMax, $iCompare) EndFunc ;==>__ArrayQuickSort2D ; #FUNCTION# ==================================================================================================================== ; Name...........: _ArraySwap ; Description ...: Swaps two items. ; Syntax.........: _ArraySwap(ByRef $vItem1, ByRef $vItem2) ; Parameters ....: $vItem1 - First item to swap ; $vItem2 - Second item to swap ; Return values .: None. ; Author ........: David Nuttall <danuttall at rocketmail dot com> ; Modified.......: Ultima - minor optimization ; Remarks .......: This function swaps the two items in place, since they're passed by reference. Regular, non-array variables can also be swapped by this function. ; Related .......: _ArrayReverse ; Link ..........: ; Example .......: Yes ; =============================================================================================================================== Func _ArraySwap(ByRef $vItem1, ByRef $vItem2) Local $vTmp = $vItem1 $vItem1 = $vItem2 $vItem2 = $vTmp EndFunc ;==>_ArraySwap ; #FUNCTION# ==================================================================================================================== ; Name...........: _ArrayReverse ; Description ...: Takes the given array and reverses the order in which the elements appear in the array. ; Syntax.........: _ArrayReverse(ByRef $avArray[, $iStart = 0[, $iEnd = 0]]) ; Parameters ....: $avArray - Array to modify ; $iStart - [optional] Index of array to start modifying at ; $iEnd - [optional] Index of array to stop modifying at ; Return values .: Success - 1 ; Failure - 0, sets @error: ; |1 - $avArray is not an array ; |2 - $iStart is greater than $iEnd ; |3 - $avArray is not a 1 dimensional array ; Author ........: Brian Keene ; Modified.......: Jos van der Zande <jdeb at autoitscript dot com> - added $iStart parameter and logic, Tylo - added $iEnd parameter and rewrote it for speed, Ultima - code cleanup, minor optimization ; Remarks .......: ; Related .......: _ArraySwap ; Link ..........: ; Example .......: Yes ; =============================================================================================================================== Func _ArrayReverse(ByRef $avArray, $iStart = 0, $iEnd = 0) If Not IsArray($avArray) Then Return SetError(1, 0, 0) If UBound($avArray, 0) <> 1 Then Return SetError(3, 0, 0) Local $vTmp, $iUBound = UBound($avArray) - 1 ; Bounds checking If $iEnd < 1 Or $iEnd > $iUBound Then $iEnd = $iUBound If $iStart < 0 Then $iStart = 0 If $iStart > $iEnd Then Return SetError(2, 0, 0) ; Reverse For $i = $iStart To Int(($iStart + $iEnd - 1) / 2) $vTmp = $avArray[$i] $avArray[$i] = $avArray[$iEnd] $avArray[$iEnd] = $vTmp $iEnd -= 1 Next Return 1 EndFunc ;==>_ArrayReverse My Freeware Page Link to comment Share on other sites More sharing options...
czardas Posted January 24, 2013 Share Posted January 24, 2013 (edited) I don't understand why I have to arge stuff that's in every computer science textbook.Hold your horses there a minute. Nobody makes you arge stuff, whatever that means. The method I invented may not be the most efficient and I suspected all along that it probably wouldn't be. judging by what I can tell, the method you have posted will also require multiple passes using qsort.EditI just did a speed comparison. Running both methods for 1000 iterations using your example array gave the following results.string conversion method 943.359561061532 msqsort method 930.61492452253So there's a 13 ms improvement with the text book method. I can live with that. I could probably lose those 13 ms with more accurate testing, but then the tests would need to be tried on different sized arrays. Edited January 24, 2013 by czardas operator64Â Â ArrayWorkshop Link to comment Share on other sites More sharing options...
MilesAhead Posted January 24, 2013 Share Posted January 24, 2013 (edited) Your code works. The benchmark is not the point. The point is, the array methods presumably have already been debugged since they have been around a long time. With the comparision injection method, you only have to implement and debug a comparison function. Since we assume for the moment that the _ArraySort function doesn't scramble the data since it's debugged, then there's less risk of scrambling the array contents. Traversing an array, changing it, sorting it, then changing it back seems more error prone to me. More stuff to debug. The point of gerneralized methods is programmer efficiency more than run-time efficiency. I think it took me about 2 minutes to pull the CustomCompare out of my head. The passing in a custom compare technique is not for every situtation. But it's definitely a reusable tool. That's why it's in stuff like standardized libraries. But just like them, C++ "containers" are not always the answer. But they are there if you don't mind throwing in the hitchen sink to save development time. I'm not saying your code is broken. Only that the "pass in the custom cmpare function" technique is resuable. Good for the toolbox. I've never seen a board so resistant to sorting algorithm implementations as here. If you look at _ArraySort() it's an implementation of QuickSort. These algorithms have been around for decades and are proven to work well for the general case. Back in the 80s someone might have argued that passing in a pointer to a function in C was slower than directly calling it. Now peope would laugh since the machines are so fast. One extra defreference might mean something with real-time applications like if you are a passenger on a mach 4 rocket. But I can't think of much else that applies. Edited January 24, 2013 by MilesAhead My Freeware Page Link to comment Share on other sites More sharing options...
czardas Posted January 24, 2013 Share Posted January 24, 2013 (edited) Your code works. The benchmark is not the point. The point is, the array methods presumably have already been debugged since they have been around a long time. With the comparision injection method, you only have to implement and debug a comparison function. Since we assume for the moment that the _ArraySort function doesn't scramble the data since it's debugged, then there's less risk of scrambling the array contents. Traversing an array, changing it, sorting it, then changing it back seems more error prone to me. More stuff to debug.The point of gerneralized methods is programmer efficiency more than run-time efficiency. I think it took me about 2 minutes to pull the CustomCompare out of my head. The passing in a custom compare technique is not for every situtation. But it's definitely a reusable tool. That's why it's in stuff like standardized libraries. But just like them, C++ "containers" are not always the answer. But they are there if you don't mind throwing in the hitchen sink to save development time.I'm not saying your code is broken. Only that the "pass in the custom cmpare function" technique is resuable. Good for the toolbox.I've never seen a board so resistant to sorting algorithm implementations as here. If you look at _ArraySort() it's an implementation of QuickSort. These algorithms have been around for decades and are proven to work well for the general case. Back in the 80s someone might have argued that passing in a pointer to a function in C was slower than directly calling it. Now peope would laugh since the machines are so fast. One extra defreference might mean something with real-time applications like if you are a passenger on a mach 4 rocket. But I can't think of much else that applies.The limitations of the above example code, which I put together in half an hour, are clear to me, and also easy to address. The advantages your method may have over mine are not apparent to me. There are some extra steps taken, but this is counterbalanced by less sort processing. I imagine your code, on the other hand, does more comparisons. but I don't quite see what's going on there.Okay, so I didn't read all the text books, but can you convince me that what I wish to achieve with AutoIt is actually in a text book? Many have failed to convince me previously, simply bacause most of those pages are actually missing. There's a lot of cool stuff to learn, for sure; but some old habits die hard. Some of it is (well hmm) not so hot. Perhaps this is down to bad architectural design choices early on, but not in every case.The most important thing for me is that I had fun solving this problem. I would have had less fun implementing a pre-made textbook solution. Edited January 24, 2013 by czardas operator64Â Â ArrayWorkshop Link to comment Share on other sites More sharing options...
benners Posted January 25, 2013 Author Share Posted January 25, 2013 (edited) Hi All,Thanks for your replies.@czardasI had something similar to your #7 post when I knew specifically which column I was going to sort and what format the column was in, then I could specify if the column was such a column convert to numbers for the sort. I thought I would improve my function so that it automatically retrieved to format and acted accordingly. I will be altering and importing the arraytable so wanted to keep the format the same without an extra step of converting back to a string.@MilesAheadI tried your code and modified the CustomCompare function to combine your codes for strings and numbers as strings (i.e versions) for my needsFunc _CustomCompare($sLeft, $sRight) If StringIsInt(StringReplace($sLeft, '.', '')) And StringIsInt(StringReplace($sRight, '.', '')) Then Local $l = StringSplit($sLeft, ".") Local $r = StringSplit($sRight, ".") For $x = 1 To $l[0] $l[$x] = Int($l[$x]) $r[$x] = Int($r[$x]) Next For $x = 1 To $l[0] If $l[$x] < $r[$x] Then Return -1 ElseIf $l[$x] = $r[$x] Then ContinueLoop Else Return 1 EndIf Next Else Return StringCompare($sLeft, $sRight) EndIf EndFunc ;==>CustomCompareThanks again Edited January 25, 2013 by benners Link to comment Share on other sites More sharing options...
kylomas Posted January 25, 2013 Share Posted January 25, 2013 (edited) benners (F.Y.I.), Here are three ways to remove periods ('.') from strings #include <array.au3> ; remove periods with string functions local $str = '24.333.1212.2.89765' local $a10 = stringsplit($str,'.',2) local $mynumber = _ArrayToString($a10,'') ConsoleWrite($mynumber & @LF) ; remove periods with regexp $mynumber = '' $mynumber = stringregexpreplace($str,'\.','') ConsoleWrite($mynumber & @LF) ; and of course the most obvious $mynumber = '' local $mynumber = stringreplace($str,'.','') ConsoleWrite($mynumber & @LF) kylomas edit: spelling and added code Edited January 25, 2013 by kylomas Forum Rules        Procedure for posting code "I like pigs. Dogs look up to us. Cats look down on us. Pigs treat us as equals." - Sir Winston Churchill Link to comment Share on other sites More sharing options...
guinness Posted January 25, 2013 Share Posted January 25, 2013 (edited) Or StringReplace() Edit: Post number 7,777. Nice! Edited January 25, 2013 by guinness UDF List:  _AdapterConnections() • _AlwaysRun() • _AppMon() • _AppMonEx() • _ArrayFilter/_ArrayReduce • _BinaryBin() • _CheckMsgBox() • _CmdLineRaw() • _ContextMenu() • _ConvertLHWebColor()/_ConvertSHWebColor() • _DesktopDimensions() • _DisplayPassword() • _DotNet_Load()/_DotNet_Unload() • _Fibonacci() • _FileCompare() • _FileCompareContents() • _FileNameByHandle() • _FilePrefix/SRE() • _FindInFile() • _GetBackgroundColor()/_SetBackgroundColor() • _GetConrolID() • _GetCtrlClass() • _GetDirectoryFormat() • _GetDriveMediaType() • _GetFilename()/_GetFilenameExt() • _GetHardwareID() • _GetIP() • _GetIP_Country() • _GetOSLanguage() • _GetSavedSource() • _GetStringSize() • _GetSystemPaths() • _GetURLImage() • _GIFImage() • _GoogleWeather() • _GUICtrlCreateGroup() • _GUICtrlListBox_CreateArray() • _GUICtrlListView_CreateArray() • _GUICtrlListView_SaveCSV() • _GUICtrlListView_SaveHTML() • _GUICtrlListView_SaveTxt() • _GUICtrlListView_SaveXML() • _GUICtrlMenu_Recent() • _GUICtrlMenu_SetItemImage() • _GUICtrlTreeView_CreateArray() • _GUIDisable() • _GUIImageList_SetIconFromHandle() • _GUIRegisterMsg() • _GUISetIcon() • _Icon_Clear()/_Icon_Set() • _IdleTime() • _InetGet() • _InetGetGUI() • _InetGetProgress() • _IPDetails() • _IsFileOlder() • _IsGUID() • _IsHex() • _IsPalindrome() • _IsRegKey() • _IsStringRegExp() • _IsSystemDrive() • _IsUPX() • _IsValidType() • _IsWebColor() • _Language() • _Log() • _MicrosoftInternetConnectivity() • _MSDNDataType() • _PathFull/GetRelative/Split() • _PathSplitEx() • _PrintFromArray() • _ProgressSetMarquee() • _ReDim() • _RockPaperScissors()/_RockPaperScissorsLizardSpock() • _ScrollingCredits • _SelfDelete() • _SelfRename() • _SelfUpdate() • _SendTo() • _ShellAll() • _ShellFile() • _ShellFolder() • _SingletonHWID() • _SingletonPID() • _Startup() • _StringCompact() • _StringIsValid() • _StringRegExpMetaCharacters() • _StringReplaceWholeWord() • _StringStripChars() • _Temperature() • _TrialPeriod() • _UKToUSDate()/_USToUKDate() • _WinAPI_Create_CTL_CODE() • _WinAPI_CreateGUID() • _WMIDateStringToDate()/_DateToWMIDateString() • Au3 script parsing • AutoIt Search • AutoIt3 Portable • AutoIt3WrapperToPragma • AutoItWinGetTitle()/AutoItWinSetTitle() • Coding • DirToHTML5 • FileInstallr • FileReadLastChars() • GeoIP database • GUI - Only Close Button • GUI Examples • GUICtrlDeleteImage() • GUICtrlGetBkColor() • GUICtrlGetStyle() • GUIEvents • GUIGetBkColor() • Int_Parse() & Int_TryParse() • IsISBN() • LockFile() • Mapping CtrlIDs • OOP in AutoIt • ParseHeadersToSciTE() • PasswordValid • PasteBin • Posts Per Day • PreExpand • Protect Globals • Queue() • Resource Update • ResourcesEx • SciTE Jump • Settings INI • SHELLHOOK • Shunting-Yard • Signature Creator • Stack() • Stopwatch() • StringAddLF()/StringStripLF() • StringEOLToCRLF() • VSCROLL • WM_COPYDATA • More Examples... Updated: 22/04/2018 Link to comment Share on other sites More sharing options...
kylomas Posted January 25, 2013 Share Posted January 25, 2013 @guinness, Yes, I forgot the most obvious. It looks like the OP is processing the string by nodes, thus, the alternative methods. kylomas Forum Rules        Procedure for posting code "I like pigs. Dogs look up to us. Cats look down on us. Pigs treat us as equals." - Sir Winston Churchill Link to comment Share on other sites More sharing options...
czardas Posted January 25, 2013 Share Posted January 25, 2013 (edited) It was interesting to try this. Often different methods are suitable for specific circumstances. The weakness that I see with what I posted is that it is limited to equal numbers of dots per item and it returns the array ByRef. That's a potential problem if an error occurs during processing, and if no countermeasures are taken. Another potential problem, as MilesAhead did mention, was that some corruption is possible. The one thing I forgot was that someone might pass a string with preceeding zeros like this: 00010.012.0006.4.00222.00034 That string would indeed become corrupted with my current implementation. I tend to use string functions a lot because they often have big speed advantages over array functions. I have received criticism for this previously, and while the assertions may sometimes be correct, I still like to see hard evidence and this isn't always forthcoming. Speed is a serious issue in some of my projects. One thing to note is that a delimitered numeric string is still a string, however you approach it. At the end of the day, MileAhead may have had a point, but ruined it by calling me an idiot for not having read lots of text books; nor do I particularly like his implementation for several reasons: The example uses function names which are identical to the standard Array UDF, so I would need to change those if I were to use his code. The code contains no additional comments outside the header, so it's hard to understand. It would also help if AutoIt code tags had been used. I'll refrain from saying any more. Edited January 25, 2013 by czardas operator64Â Â ArrayWorkshop Link to comment Share on other sites More sharing options...
MilesAhead Posted January 25, 2013 Share Posted January 25, 2013 Your opposition to standard sorting techniques where a comparison function is passed in is a position abandoned by just about everyone else decades ago. If you feel foolish for this opposition, I don;'t see that as my problem. The code I posted was a simple test stub to suggest a minor modification to the UDF in question to avoid just such scenarios as traversing arrays, modifying them, sorting and then removing the modification. Unless there's some constraint that mandates doing things that way, it seems rather tedioius and unnecessary to me. But since I first posted the test code further searches turned up another poster suggesting much the same improvements back in 2007. For some reason there seems to be an irrational resistance that makes pursuing this and like topics pointless. I don't understand the emotional component on display in this thread. It's like someone not liking me because they found out I once used HeapSort(). Really bizarre. My Freeware Page Link to comment Share on other sites More sharing options...
czardas Posted January 25, 2013 Share Posted January 25, 2013 We are all here to learn. operator64Â Â ArrayWorkshop 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