lesmly Posted September 29, 2016 Share Posted September 29, 2016 (edited) I have a problem - I'd be able to write it but using a very large number of IF, and maybe it is a much simpler way? I have a two-dimensional table: in the first row is a number from 1 to 7 in the second row: numerical value (an integer from 0 inclusive to... not know). It happens that one or more of these values are empty - then I can take any value, eg. negative. And now I have to sort of the second line from the smallest to the largest, and blank values at the end. Of course, numbers from first row must also be appropriately sort. example: I have 1 2 3 4 5 6 7 100 30 -1 0 -1 60 100 I want to receive 4 2 6 1 7 3 5 0 30 60 100 100 -1 -1 Edited September 29, 2016 by lesmly Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted September 29, 2016 Moderators Share Posted September 29, 2016 lesmly, This seems to work: #include <Array.au3> Global $aTable[][] = [[1, 2, 3, 4, 5, 6, 7], [100, 30, -1, 0, -1, 60, 100]] ; Transpose table _ArrayTranspose($aTable) ;_ArrayDisplay($aTable, "Transposed", Default, 8) ; Sort on second column _ArraySort($aTable, 1, 0, 0, 1) ;_ArrayDisplay($aTable, "Sorted", Default, 8) ; Reset to original format _ArrayTranspose($aTable) _ArrayDisplay($aTable, "Result", Default, 8) Good enough for what you need? 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...
lesmly Posted September 29, 2016 Author Share Posted September 29, 2016 (edited) Almost ... You sort from highest value but I need from lowest exept empty (negative). I need: 4 2 6 1 7 3 5 0 30 60 100 100 -1 -1 Your script: 7 1 6 2 4 3 5 100 100 60 30 0 -1 -1 Edited September 29, 2016 by lesmly Link to comment Share on other sites More sharing options...
czardas Posted September 29, 2016 Share Posted September 29, 2016 (edited) You could try ArrayWorkshop in my signature. I think this does what you want. #include <ArrayWorkshop.au3> #include <Array.au3> ; for ArrayDisplay() Local $aArray = [[1,2,3,4,5,6,7],[100,30,' ',0,' ',60,100]] _ArrayDisplay($aArray) Local $aNew[1], $a2 For $i = 0 To UBound($aArray) -1 $a2 = _ExtractRegion($aArray, 1, $i) ; grab each row _ArraySortXD($a2, 2, 2) ; sort numeric (dimension = 2) _ArrayAttach($aNew, $a2) ; attach the result to the new array Next _DeleteRegion($aNew) ; delete the empty row (that we started with) in $aNew _ArrayDisplay($aNew) Edit: I'm assuming the values of -1 are replacements. Edited September 29, 2016 by czardas lesmly 1 operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
AutoBert Posted September 29, 2016 Share Posted September 29, 2016 (edited) Here the beginning of a other solution: #include <Array.au3> #include <arraySort2D_MC.au3> Global $aTable[][] = [[1, 2, 3, 4, 5, 6, 7], [100, 30, -1, 0, -1, 60, 100]] _arraySort2D_MC($aTable, "1%N|0",0,0,0,False,True) _ArrayDisplay($aTable, "Result", Default, 8) therefor needed: expandcollapse popupFunc _arraySort2D_MC(ByRef $avArray, $ColOrder, $iStart = 0, $iEnd = 0, $iDesc = 0, $bDelDuplictes = False, $bTranspose = False) ;Parameterübergabe ;$avArray zu sorterendes Array ;$ColdOrder String mit den Sortieranweisungen, getrennt mit "|" für jede Spalte ; zulässige Angaben: ; nur Spaltenindex = normale Sortierung ; Spaltenindex%N = numerische Sortierung ; Spaltenindex%D = Sortierung nach Datum JJJJ/MM/TT ; Spaltenindex%G = Sortierung nach Geburtstag MM/TT/JJJJ ; z.B.: "1|2%N|3%D|0" die Reihenfolge für die Sortierung ist 1.,2., 3. 0. (0 basierend) ; die 1. Spalte wird Standard von _ArraySort verwendet ; die 2. Spalte (%N) wird bei der Sortierun numerisch behnadelt ; die 3. Spalte (%D) wird als Datum behandelt ; ; es müssen alle Spalten des Arrays in den Sortieranweisungen vorkommen ;$iStart Zeile bei der die Sortierung beginnt (OPTIONAL) ;$iEnd Zeile bei der die Sortierung endet (OPTIONAL) ;$iDesc Absteigend 1 = JA 0 = NEIN (OPTIONAL) ;$bDelDuplictes nur einmalige Zeilen zulassen True = Jede Zeile ist einmalig ; False = Es werden alle Zeilen ausgegeben ;$bTranspose nach Zeilen sortieren True = Sortierung nach Zeilen ; False = Sortierung nach Spalten ; ===================================================================== ;Rückgabe: 0 Fehler (nicht alle Spalten in $ColOrder definert ; 1 Erfolg ;Autor: AutoBert 2010 erweeitert 2012 ;============================================================================================================== If $bTranspose Then _ArrayTranspose($avArray) Local $iDims = UBound($avArray, 0) If @error Or $iDims <> 2 Then MsgBox(16, "Fehler:", "kein 2D-Array") Return 0 EndIf If $iEnd = 0 Then $iEnd = UBound($avArray) - 1 If $iEnd > UBound($avArray) - 1 Then $iEnd = UBound($avArray) - 1 $aCols = StringSplit($ColOrder, "|") ;consolewrite($aCols[0] & " " & UBound($array, 2) & @CRLF) If $aCols[0] <> UBound($avArray, 2) Then MsgBox(16, "Fehler:", "unterschiedliche Spaltenanzahl!") Return 0 EndIf Local Const $sLeer = " " Local $aColformat = $aCols Local $sRow For $i = 1 To $aColformat[0] ;$aColformat[$i] = StringRight($aColformat[$i], 1) $aCols[$i] = StringReplace($aCols[$i], "N", "") $aCols[$i] = StringReplace($aCols[$i], "D", "") Next _ArrayDelete($aColformat, 0) _ArrayDelete($aCols, 0) Local $iCols = UBound($aColformat) For $i = $iStart To $iEnd $sRow = "" For $j = 0 To $iCols - 1 $iCol = $aCols[$j] Switch StringUpper(StringRight($aColformat[$j], 1)) Case "N" ;numerisch $aNum = StringSplit($avArray[$i][$iCol], ",") If IsArray($aNum) Then If $aNum[0] = 1 Then _ArrayAdd($aNum, " ") $sRow &= StringRight($sLeer & $aNum[1] & "," & StringLeft($aNum[2]&$sLeer, 30), 99) Else $sRow &= StringRight($sLeer & $aNum[1], 99) EndIf Case "D" ;Datum JJJJ/MM/TT ;consolewrite("D: " & $aColformat[$j] & " " & $avArray[$i][$iCols]) $aDate = StringSplit($avArray[$i][$iCol], ".") If IsArray($aDate) Then $sRow &= $aDate[3] & "." & StringRight("0" & $aDate[2], 2) & "." & StringRight("0" & $aDate[1], 2) Case "G" ;Geburtstags-Datum MM/TT/JJJJ ;consolewrite("D: " & $aColformat[$j] & " " & $avArray[$i][$iCols]) $aDate = StringSplit($avArray[$i][$iCol], ".") If IsArray($aDate) Then $sRow &= StringRight("0" & $aDate[2], 2) & "." & StringRight("0" & $aDate[1], 2) & "." & $aDate[3] Case Else $sRow &= $avArray[$i][$iCol] EndSwitch If $j <> $iCols - 1 Then $sRow &= "|" Next $avArray[$i][0] = $sRow ;consolewrite($sRow & @CRLF) Next _ArraySort($avArray, $iDesc, $iStart, $iEnd) If $bDelDuplictes Then For $i = $iEnd - 1 To $iStart Step -1 If $avArray[$i][0] = $avArray[$i + 1][0] Then _ArrayDelete($avArray, $i + 1) $iEnd -= 1 EndIf Next EndIf ;_ArrayDisplay($avArray) ;_ArrayDisplay($aColformat, "FormatStrings") ;_ArrayDisplay($aCols, "Cols") ;consolewrite($iCols & @CRLF) For $i = $iStart To $iEnd ;consolewrite($avArray[$i][0] & @CRLF) $aSplit = StringSplit($avArray[$i][0], "|", 2) For $j = 0 To $iCols - 1 $iCol = $aCols[$j] Switch StringRight($aColformat[$j], 1) ; Case "X" ;#cs Case "N" ;numerisch $avArray[$i][$iCol] = StringReplace($aSplit[$j], " ", "") if StringRight($avArray[$i][$iCol],1)="," Then $avArray[$i][$iCol] = StringTrimRight($avArray[$i][$iCol], 1) ;consolewrite(" N: " & $avArray[$i][$iCol]) Case "D" ;Datum JJJJ/MM/TT $aDate = StringSplit($aSplit[$j], ".") $avArray[$i][$iCol] = StringReplace($aDate[3] & "." & $aDate[2] & "." & $aDate[1], "_", "") ;consolewrite(" D: " & $avArray[$i][$iCol]) Case "G" ;Geburtstags-Datum MM/TT/JJJJ $aDate = StringSplit($aSplit[$j], ".") $avArray[$i][$iCol] = StringReplace($aDate[2] & "." & $aDate[1] & "." & $aDate[3], "_", "") ;consolewrite(" D: " & $avArray[$i][$iCol]) ;#ce Case Else $avArray[$i][$iCol] = $aSplit[$j] ;consolewrite(" : " & $avArray[$i][$iCol]) EndSwitch Next ;consolewrite(@CRLF) Next If $bTranspose Then _ArrayTranspose($avArray) Return 1 ;_ArrayDisplay($avArray) EndFunc ;==>_arraySort2D_MC but the end of the job, moving <=0 must be done by you. Edited September 29, 2016 by AutoBert transposing moved into udf lesmly 1 Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted September 29, 2016 Moderators Share Posted September 29, 2016 lesmly, Not too hard to fix: #include <Array.au3> Global $aTable[][] = [[1, 2, 3, 4, 5, 6, 7], [100, 30, -1, 0, -1, 60, 100]] ; Transpose table _ArrayTranspose($aTable) ; Remove negatives Local $aNegTable[UBound($aTable)][UBound($aTable, 2)], $iNegIndex = 0 For $i = UBound($aTable) - 1 To 0 Step -1 If $aTable[$i][1] < 0 Then $aNegTable[$iNegIndex][0] = $aTable[$i][0] $aNegTable[$iNegIndex][1] = $aTable[$i][1] $iNegIndex += 1 _ArrayDelete($aTable, $i) EndIf Next ; Correct neg table size ReDim $aNegTable[2][$iNegIndex] ;_ArrayDisplay($aTable, "", Default, 8) ;_ArrayDisplay($aNegTable, "", Default, 8) ; Sort on second column _ArraySort($aTable, 0, 0, 0, 1) ;_ArrayDisplay($aTable, "Sorted", Default, 8) ; Rejoin arrays _ArrayConcatenate($aTable, $aNegTable) ; Reset to original format _ArrayTranspose($aTable) _ArrayDisplay($aTable, "Result", Default, 8) M23 lesmly 1 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...
czardas Posted September 29, 2016 Share Posted September 29, 2016 (edited) LOL! I didn't read this carefully enough (or rather I presumed there was a mistake which was incorrect). I was a bit rushed. You only actually need one line of code. #include <ArrayWorkshop.au3> #include <Array.au3> ; for ArrayDisplay() Local $aArray = [[1,2,3,4,5,6,7],[100,30,' ',0,' ',60,100]] _ArrayDisplay($aArray) _ArraySortXD($aArray, 2, 2, -1, 1) ; dimension to sort = 2, numeric sort, whole array, sort on 1st dimension index = 1 _ArrayDisplay($aArray) Edit: If your numbers include numeric strings then you can use this instead: ; dimension to sort = 2 (cols), numeric sort = 2 + (numeric strings = 256), end value = -1, 1st dimension vector index = 1 (2nd row) _ArraySortXD($aArray, 2, 2 + 256, -1, 1) Edited September 30, 2016 by czardas 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