gcue Posted January 5, 2011 Share Posted January 5, 2011 (edited) hello. i am trying to sort a multi-column array. here is an example array: local $array[3][3] $array[0][0] = "D002222" $array[0][1] = "002129" $array[0][2] = "948" $array[1][0] = "D003333" $array[1][1] = "002127" $array[1][2] = "200" $array[2][0] = "D001111" $array[2][1] = "002124" $array[2][2] = "6789" i would like to sort first by column 1 then by column 2 then by column 3 thank you for your help in advance =) Edited January 5, 2011 by gcue Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted January 5, 2011 Moderators Share Posted January 5, 2011 gcue,Two comments:- 1. What have you tried so far? - 2. You need to be much more specific as to the result you want. "sort first by column 1 then by column 2 then by column 3" can mean many things - my impression of what you are looking for is this:A A A A A B A B A A B B B A A B A B B B A B B BIs that also what you envisage? M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
iamtheky Posted January 5, 2011 Share Posted January 5, 2011 (edited) as well, you will have to enter numbers without quotes, otherwise it will treat them as strings. Run the following and it sorts them in one after the other. throw the 3rd element back into quotes and you will see 6789 stay in the middle of the last array. #include <array.au3> local $array[3][3] $array[0][0] = "D002222" $array[0][1] = "002129" $array[0][2] = 948 $array[1][0] = "D003333" $array[1][1] = "002127" $array[1][2] = 200 $array[2][0] = "D001111" $array[2][1] = "002124" $array[2][2] = 6789 _ArraySort ($array , 0 , 0 , 0 , 0) _ArrayDisplay ($array) _ArraySort ($array , 0 , 0 , 0 , 1) _ArrayDisplay ($array) _ArraySort ($array , 0 , 0 , 0 , 2) _ArrayDisplay ($array) Edited January 5, 2011 by iamtheky ,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-. |(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/ (_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_) | | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) ( | | | | |)| | \ / | | | | | |)| | `--. | |) \ | | `-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_| '-' '-' (__) (__) (_) (__) Link to comment Share on other sites More sharing options...
UEZ Posted January 5, 2011 Share Posted January 5, 2011 (edited) Try this: expandcollapse popup#include <array.au3> $max = 50 $s = "" Dim $array[$max][4] for $i = 0 to $max - 1 $array[$i][0] = Chr(Random(65, 67, 1)) & Chr(Random(65, 67, 1)) & Chr(Random(65, 67, 1)) & Chr(Random(65, 67, 1)) For $j = 0 To 2 If Random(0, 1, 1) Then $s &= Chr(Random(48, 57, 1)) Next If $s = "" Then $s = Chr(Random(65, 67, 1)) $array[$i][1] = $s $array[$i][2] = Random(1, 10, 1) $m = Random(1, 12, 1) $d = Random(1, 31, 1) If $m < 10 Then $m = "0" & $m If $d < 10 Then $d = "0" & $d $array[$i][3] = Random(1900, 2010, 1) & "-" & $m & "-" & $d $s = "" Next _ArrayDisplay($array, 'Before:') Dim $aI[3] ;order of sorting rows - here row 0,3,2 $aI[0] = 0 $aI[1] = 3 $aI[2] = 2 _ArraySort_MultiColumn($array, $aI) _ArrayDisplay($array, 'After:') ; #FUNCTION# ============================================================================= ; Name.............: _ArraySort_MultiColumn ; Description ...: sorts an array at given colums (multi colum sort) ; Syntax...........: _ArraySort_MultiColumn(ByRef $aSort, ByRef $aIndices) ; Parameters ...: $aSort - array to sort ; $aIndices - array with colum indices which should be sorted in specified order - zero based ; $oDir/$iDir - sort direction - if set to 1, sort descendingly else ascendingly ; Author .........: UEZ ; Version ........: v0.70 build 2013-11-20 Beta ; ========================================================================================= Func _ArraySort_MultiColumn(ByRef $aSort, ByRef $aIndices, $oDir = 0, $iDir = 0) If Not IsArray($aIndices) Or Not IsArray($aSort) Then Return SetError(1, 0, 0) ;checks if $aIndices is an array If UBound($aIndices) > UBound($aSort, 2) Then Return SetError(2, 0, 0) ;check if $aIndices array is greater the $aSort array Local $1st, $2nd, $x, $j, $k, $l = 0 For $x = 0 To UBound($aIndices) - 1 ;check if array content makes sense If Not IsInt($aIndices[$x]) Then Return SetError(3, 0, 0) ;array content is not numeric Next If UBound($aIndices) = 1 Then Return _ArraySort($aSort, $oDir, 0, 0, $aIndices[0]) ;check if only one index is given _ArraySort($aSort, $oDir, 0, 0, $aIndices[0]) Do $1st = $aIndices[$l] $2nd = $aIndices[$l + 1] $j = 0 $k = 1 While $k < UBound($aSort) If $aSort[$j][$1st] <> $aSort[$k][$1st] Then If $k - $j > 1 Then _ArraySort($aSort, $iDir , $j, $k - 1, $2nd) $j = $k Else $j = $k EndIf EndIf $k += 1 WEnd If $k - $j > 1 Then _ArraySort($aSort, $iDir, $j, $k, $2nd) $l += 1 Until $l = UBound($aIndices) - 1 Return 1 EndFuncIf you find a bug please report.Br,UEZ Edited November 20, 2013 by UEZ OSMMDAIJI 1 Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
gcue Posted January 5, 2011 Author Share Posted January 5, 2011 UEZ, that works perfectly!!!! many thanks =) Try this: expandcollapse popup#include <Array.au3> $max = 50 $s = "" Dim $array[$max][4] for $i = 0 to $max - 1 $array[$i][0] = Chr(Random(65, 67, 1)) & Chr(Random(65, 67, 1)) & Chr(Random(65, 67, 1)) & Chr(Random(65, 67, 1)) For $j = 0 To 2 If Random(0, 1, 1) Then $s &= Chr(Random(48, 57, 1)) Next If $s = "" Then $s = Chr(Random(65, 67, 1)) $array[$i][1] = $s $array[$i][2] = Random(1, 10, 1) $m = Random(1, 12, 1) $d = Random(1, 31, 1) If $m < 10 Then $m = "0" & $m If $d < 10 Then $d = "0" & $d $array[$i][3] = Random(1900, 2010, 1) & "-" & $m & "-" & $d $s = "" Next _ArrayDisplay($array, 'Before:') Dim $aI[3] ;order of sorting rows - here row 0,3,2 $aI[0] = 0 $aI[1] = 3 $aI[2] = 2 _ArraySort_MultiColumn($array, $aI) _ArrayDisplay($array, 'After:') ; #FUNCTION# ============================================================================= ; Name...........: _ArraySort_MultiColumn ; Description ...: sorts an array at given colums (multi colum sort) ; Syntax.........: _ArraySort_MultiColumn(ByRef $aSort, ByRef $aIndices) ; Parameters ....: $aSort - array to sort ; $aIndices - array with colum indices which should be sorted in specified order - zero based ; $dir - sort direction - if set to 1, sort descendingly ; Author ........: UEZ ; Version .......: v0.60 build 2010-07-04 Beta ; ========================================================================================= Func _ArraySort_MultiColumn(ByRef $aSort, ByRef $aIndices, $oDir = 0, $iDir = 0) Local $1st, $2nd If Not IsArray($aIndices) Or Not IsArray($aSort) Then ;checks if $aIndices is an array Return SetError(1, 0, 0) ;no array EndIf If UBound($aIndices) > UBound($aSort, 2) Then ;check if $aIndices array is greater the $aSort array Return SetError(2, 0, 0) ;$aIndices array is greater EndIf Local $x For $x = 0 To UBound($aIndices) - 1 ;check if array content makes sense If Not IsInt($aIndices[$x]) Then Return SetError(3, 0, 0) ;array content is not numeric EndIf Next If UBound($aIndices) = 1 Then ;check if only one index is given Return _ArraySort($aSort, $oDir, 0, 0, $aIndices[0]) EndIf Local $j, $k, $l = 0 _ArraySort($aSort, $oDir, 0, 0, $aIndices[0]) Do $1st = $aIndices[$l] $2nd = $aIndices[$l + 1] $j = 0 $k = 1 While $k < UBound($aSort) If $aSort[$j][$1st] <> $aSort[$k][$1st] Then If $k - $j > 1 Then _ArraySort($aSort, $iDir , $j, $k - 1, $2nd) $j = $k Else $j = $k EndIf EndIf $k += 1 WEnd If $k - $j > 1 Then _ArraySort($aSort, $oDir, $j, $k, $2nd) $l += 1 Until $l = UBound($aIndices) - 1 Return SetError(0, 0, 1) EndFunc If you find a bug please report. Br, UEZ Link to comment Share on other sites More sharing options...
gcue Posted January 5, 2011 Author Share Posted January 5, 2011 hey Melba, i was using Geosoft's udf _ArraySortClib to do my sorting before but could not get it to work with multi-sorting http://dundats.mvps.org/autoit/udf_code.aspx?udf=arrayx thanks! gcue, Two comments: - 1. What have you tried so far? - 2. You need to be much more specific as to the result you want. "sort first by column 1 then by column 2 then by column 3" can mean many things - my impression of what you are looking for is this: A A A A A B A B A A B B B A A B A B B B A B B B Is that also what you envisage? M23 Link to comment Share on other sites More sharing options...
kescho Posted November 20, 2013 Share Posted November 20, 2013 (edited) Try this: expandcollapse popup#include <array.au3> $max = 50 $s = "" Dim $array[$max][4] for $i = 0 to $max - 1 $array[$i][0] = Chr(Random(65, 67, 1)) & Chr(Random(65, 67, 1)) & Chr(Random(65, 67, 1)) & Chr(Random(65, 67, 1)) For $j = 0 To 2 If Random(0, 1, 1) Then $s &= Chr(Random(48, 57, 1)) Next If $s = "" Then $s = Chr(Random(65, 67, 1)) $array[$i][1] = $s $array[$i][2] = Random(1, 10, 1) $m = Random(1, 12, 1) $d = Random(1, 31, 1) If $m < 10 Then $m = "0" & $m If $d < 10 Then $d = "0" & $d $array[$i][3] = Random(1900, 2010, 1) & "-" & $m & "-" & $d $s = "" Next _ArrayDisplay($array, 'Before:') Dim $aI[3] ;order of sorting rows - here row 0,3,2 $aI[0] = 0 $aI[1] = 3 $aI[2] = 2 _ArraySort_MultiColumn($array, $aI) _ArrayDisplay($array, 'After:') ; #FUNCTION# ============================================================================= ; Name.............: _ArraySort_MultiColumn ; Description ...: sorts an array at given colums (multi colum sort) ; Syntax...........: _ArraySort_MultiColumn(ByRef $aSort, ByRef $aIndices) ; Parameters ...: $aSort - array to sort ; $aIndices - array with colum indices which should be sorted in specified order - zero based ; $dir - sort direction - if set to 1, sort descendingly ; Author .........: UEZ ; Version ........: v0.60 build 2011-04-19 Beta ; ======================================================================================== Func _ArraySort_MultiColumn(ByRef $aSort, ByRef $aIndices, $oDir = 0, $iDir = 0) Local $1st, $2nd If Not IsArray($aIndices) Or Not IsArray($aSort) Then Return SetError(1, 0, 0) ;checks if $aIndices is an array If UBound($aIndices) > UBound($aSort, 2) Then Return SetError(2, 0, 0) ;check if $aIndices array is greater the $aSort array Local $x For $x = 0 To UBound($aIndices) - 1 ;check if array content makes sense If Not IsInt($aIndices[$x]) Then Return SetError(3, 0, 0) ;array content is not numeric Next If UBound($aIndices) = 1 Then Return _ArraySort($aSort, $oDir, 0, 0, $aIndices[0]) ;check if only one index is given Local $j, $k, $l = 0 _ArraySort($aSort, $oDir, 0, 0, $aIndices[0]) Do $1st = $aIndices[$l] $2nd = $aIndices[$l + 1] $j = 0 $k = 1 While $k < UBound($aSort) If $aSort[$j][$1st] <> $aSort[$k][$1st] Then If $k - $j > 1 Then _ArraySort($aSort, $iDir , $j, $k - 1, $2nd) $j = $k Else $j = $k EndIf EndIf $k += 1 WEnd If $k - $j > 1 Then _ArraySort($aSort, $oDir, $j, $k, $2nd) $l += 1 Until $l = UBound($aIndices) - 1 Return 1 EndFunc If you find a bug please report. Br, UEZ Hi UEZ! I think I found a bug in your UDF. If I have an array with 2 columns and when sorting descending by column 2 and also ascending by column 1 then all items are sorted as I want except the last one. example: col1 col2 10 3 11 3 12 3 10 2 11 2 12 2 12 1 11 1 10 1 The problem is commented in the code below: WEnd If $k - $j > 1 Then _ArraySort($aSort, $oDir, $j, $k, $2nd) ;<<<<<<<<<<<< $oDir has to be changed to $iDir $l += 1 expandcollapse popup; #FUNCTION# ============================================================================= ; Name.............: _ArraySort_MultiColumn ; Description ...: sorts an array at given colums (multi colum sort) ; Syntax...........: _ArraySort_MultiColumn(ByRef $aSort, ByRef $aIndices) ; Parameters ...: $aSort - array to sort ; $aIndices - array with colum indices which should be sorted in specified order - zero based ; $dir - sort direction - if set to 1, sort descendingly ; Author .........: UEZ ; Version ........: v0.60 build 2011-04-19 Beta ; ======================================================================================== Func _ArraySort_MultiColumn(ByRef $aSort, ByRef $aIndices, $oDir = 0, $iDir = 0) Local $1st, $2nd If Not IsArray($aIndices) Or Not IsArray($aSort) Then Return SetError(1, 0, 0) ;checks if $aIndices is an array If UBound($aIndices) > UBound($aSort, 2) Then Return SetError(2, 0, 0) ;check if $aIndices array is greater the $aSort array Local $x For $x = 0 To UBound($aIndices) - 1 ;check if array content makes sense If Not IsInt($aIndices[$x]) Then Return SetError(3, 0, 0) ;array content is not numeric Next If UBound($aIndices) = 1 Then Return _ArraySort($aSort, $oDir, 0, 0, $aIndices[0]) ;check if only one index is given Local $j, $k, $l = 0 _ArraySort($aSort, $oDir, 0, 0, $aIndices[0]) Do $1st = $aIndices[$l] $2nd = $aIndices[$l + 1] $j = 0 $k = 1 While $k < UBound($aSort) If $aSort[$j][$1st] <> $aSort[$k][$1st] Then If $k - $j > 1 Then _ArraySort($aSort, $iDir , $j, $k - 1, $2nd) $j = $k Else $j = $k EndIf EndIf $k += 1 WEnd If $k - $j > 1 Then _ArraySort($aSort, $oDir, $j, $k, $2nd) ;<<<<<<<<<<<< $oDir has to be changed to $iDir $l += 1 Until $l = UBound($aIndices) - 1 Return 1 EndFunc It's only a small bug, but after correcting it everything works as it should. Edited November 20, 2013 by kescho UEZ 1 Link to comment Share on other sites More sharing options...
UEZ Posted November 20, 2013 Share Posted November 20, 2013 Thanks you very much kescho for reporting the bug!I will check and modify the function appropriately.Br,UEZ Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ 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