Sign in to follow this  
Followers 0
mary

Array Multi-Column Sort

6 posts in this topic

As you know, we can Sort 2D array with _ArraySort UDF function or with Excel or with sqlite (order by colum1 asc, coulum2 Desc, colum3 asc ...etc).

But is there an other raw algorithme to implement it in pure autoit language ?: i.e same thing like :

_ArrayMultiSort (ByRef $Array, $ColumIndex1, $ColumIndex2,$ColumIndex3....)

Share this post


Link to post
Share on other sites



Hi,

here is a VB code which maybe interesting for you

http://www.online-excel.de/excel/singsel_vba.php?f=97

Mega


Scripts & functions Organize Includes Let Scite organize the include files

Yahtzee The game "Yahtzee" (Kniffel, DiceLion)

LoginWrapper Secure scripts by adding a query (authentication)

_RunOnlyOnThis UDF Make sure that a script can only be executed on ... (Windows / HD / ...)

Internet-Café Server/Client Application Open CD, Start Browser, Lock remote client, etc.

MultipleFuncsWithOneHotkey Start different funcs by hitting one hotkey different times

Share this post


Link to post
Share on other sites

As you know, we can Sort 2D array with _ArraySort UDF function or with Excel or with sqlite (order by colum1 asc, coulum2 Desc, colum3 asc ...etc).

But is there an other raw algorithme to implement it in pure autoit language ?: i.e same thing like :

_ArrayMultiSort (ByRef $Array, $ColumIndex1, $ColumIndex2,$ColumIndex3....)

This is a simple version I wrote some time ago for a particular application. It can sort on upto 3 columns.

#include <array.au3>
Func _MyArraySort(ByRef $avArray, $iCol1 = 1, $iCol2 = 2, $iCol3 = 3)
  Local $iStart = 1
  Local $iEnd = 0
  Local $iLastRow = 0
  ; Sort on the first column
  _ArraySort($avArray, 0, $iStart, $iEnd, $iCol1)

  ; For each group of values in the first column sort the second column
  $iStart = -1
  $iLastRow = $avArray[0][0]
  For $i = 1 To $iLastRow
    Switch $i
      Case 1
        If $i <> $iLastRow Then
          If ($avArray[$i][$iCol1] <> $avArray[$i + 1][$iCol1]) Then
            $iStart = $i
            $iEnd = $iStart
          Else
            $iStart = 1
            $iEnd = $iStart
          EndIf
        EndIf
      Case $iLastRow
        $iEnd = $iLastRow
        If $iStart <> $iEnd Then
          _ArraySort($avArray, 0, $iStart, $iEnd, $iCol2)
        EndIf
      Case Else 
        If ($avArray[$i][$iCol1] <> $avArray[$i + 1][$iCol1]) Then
          $iEnd = $i
          If $iStart <> $iEnd Then
            _ArraySort($avArray, 0, $iStart, $iEnd, $iCol2)
          EndIf
          $iStart = $i + 1
          $iEnd = $iStart
        Else
          $iEnd = $i
        EndIf
    EndSwitch
  Next
  
  ; For each group of values in the second column sort the third column
  $iStart = -1
  For $i = 1 To $iLastRow
    Switch $i
      Case 1
        If $i <> $iLastRow Then
          If ($avArray[$i][$iCol1] <> $avArray[2][$iCol1]) Or ($avArray[$i][$iCol2] <> $avArray[2][$iCol2]) Then
            $iStart = 2
            $iEnd = $iStart
          Else
            $iStart = 1
            $iEnd = $iStart
          EndIf
        EndIf
      Case $iLastRow
        $iEnd = $iLastRow
        If $iStart <> $iEnd Then
          _ArraySort($avArray, 0, $iStart, $iEnd, $iCol3)
        EndIf
      Case Else 
        If ($avArray[$i][$iCol1] <> $avArray[$i + 1][$iCol1]) Or ($avArray[$i][$iCol2] <> $avArray[$i + 1][$iCol2]) Then
          $iEnd = $i
          If $iStart <> $iEnd Then
            _ArraySort($avArray, 0, $iStart, $iEnd, $iCol3)
          EndIf
          $iStart = $i + 1
          $iEnd = $iStart
        Else
          $iEnd = $i
        EndIf
    EndSwitch
  Next
EndFunc   ;==>_MyArraySort

"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to build bigger and better idiots. So far, the universe is winning."- Rick Cook

Share this post


Link to post
Share on other sites

I obviously messed up when I posted my original cut down version and didn't check that it worked. Below is the current version I use which sorts correctly.

#include <array.au3>

Opt("MustDeclareVars", 1)

Local $array[7][4] = [["26", "8", "N", "0"],["25", "9", "2", "0"],["26", "9", "S", "0"],["?", "?", "?", "?"],["25", "8", "H", "0"],["26", "9", "H", "0"],["26", "9", "N", "0"]]

_ArraySortEx($array,0,0, 0, 1, 2)
_ArrayDisplay($array)

Func _ArraySortEx(ByRef $avArray, $iStartRow = 1, $iEndRow = 0, $iCol1 = 0, $iCol2 = -1, $iCol3 = -1, $iCol4 = -1)
  Local $iLastRow = 0
  Local $iStart = -1
  Local $iEnd = -1

  If $iCol1 >= 0 Then
    ; Sort on the first column
    _ArraySort($avArray, 0, $iStartRow, $iEndRow, $iCol1)

    If $iCol2 >= 0 Then
      ; For each group of values in the first column sort the second column
      $iStart = -1
      $iLastRow = UBound($avArray) - 1
      For $i = $iStartRow To $iLastRow
        Switch $i
          Case $iStartRow
            If $i <> $iLastRow Then
              If ($avArray[$i][$iCol1] <> $avArray[$i + 1][$iCol1]) Then
                $iStart = $i
                $iEnd = $i
              Else
                $iStart = $i
                $iEnd = $i + 1
              EndIf
            EndIf
          Case $iLastRow
            $iEnd = $iLastRow
            If $iStart <> $iEnd Then
              _ArraySort($avArray, 0, $iStart, $iEnd, $iCol2)
            EndIf
          Case Else
            If ($avArray[$i][$iCol1] <> $avArray[$i + 1][$iCol1]) Then
              $iEnd = $i
              If $iStart <> $iEnd Then
                _ArraySort($avArray, 0, $iStart, $iEnd, $iCol2)
              EndIf
              $iStart = $i + 1
              $iEnd = $iStart
            Else
              $iEnd = $i
            EndIf
        EndSwitch
      Next

      If $iCol3 >= 0 Then
        ; For each group of values in the second column sort the third column
        $iStart = -1
        For $i = 1 To $iLastRow
          Switch $i
            Case 1
              If $i <> $iLastRow Then
                If ($avArray[$i][$iCol1] <> $avArray[2][$iCol1]) Or ($avArray[$i][$iCol2] <> $avArray[2][$iCol2]) Then
                  $iStart = 2
                  $iEnd = $iStart
                Else
                  $iStart = 1
                  $iEnd = $iStart
                EndIf
              EndIf
            Case $iLastRow
              $iEnd = $iLastRow
              If $iStart <> $iEnd Then
                _ArraySort($avArray, 0, $iStart, $iEnd, $iCol3)
              EndIf
            Case Else
              If ($avArray[$i][$iCol1] <> $avArray[$i + 1][$iCol1]) Or ($avArray[$i][$iCol2] <> $avArray[$i + 1][$iCol2]) Then
                $iEnd = $i
                If $iStart <> $iEnd Then
                  _ArraySort($avArray, 0, $iStart, $iEnd, $iCol3)
                EndIf
                $iStart = $i + 1
                $iEnd = $iStart
              Else
                $iEnd = $i
              EndIf
          EndSwitch
        Next

        If $iCol4 >= 0 Then
          ; For each group of values in the third column sort the forth column
          $iStart = -1
          For $i = 1 To $iLastRow
            Switch $i
              Case 1
                If $i <> $iLastRow Then
                  If ($avArray[$i][$iCol1] <> $avArray[2][$iCol1]) Or ($avArray[$i][$iCol2] <> $avArray[2][$iCol2]) Or ($avArray[$i][$iCol3] <> $avArray[2][$iCol3]) Then
                    $iStart = 2
                    $iEnd = $iStart
                  Else
                    $iStart = 1
                    $iEnd = $iStart
                  EndIf
                EndIf
              Case $iLastRow
                $iEnd = $iLastRow
                If $iStart <> $iEnd Then
                  _ArraySort($avArray, 0, $iStart, $iEnd, $iCol4)
                EndIf
              Case Else
                If ($avArray[$i][$iCol1] <> $avArray[$i + 1][$iCol1]) Or ($avArray[$i][$iCol2] <> $avArray[$i + 1][$iCol2]) Or ($avArray[$i][$iCol3] <> $avArray[$i + 1][$iCol3]) Then
                  $iEnd = $i
                  If $iStart <> $iEnd Then
                    _ArraySort($avArray, 0, $iStart, $iEnd, $iCol4)
                  EndIf
                  $iStart = $i + 1
                  $iEnd = $iStart
                Else
                  $iEnd = $i
                EndIf
            EndSwitch
          Next
        EndIf
      EndIf
    EndIf
  EndIf
EndFunc   ;==>_ArraySortEx

"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to build bigger and better idiots. So far, the universe is winning."- Rick Cook

Share this post


Link to post
Share on other sites

Thanks a lot :idea:

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

I recently posted another function that should also work, the _ArrayMultiSort function >here. 

In that post the example uses:-

_ArrayMultiSort($aList, "2a,1a") ; First sort column 2, ascending (file extensions).  Then sort column 1, ascending. Column 0 is thus sorted accordingly.

All the columns of an array can be sorted in any order, and either ascending or descending, as specified in the 2nd parameter, "$sSort", of the  _ArrayMultiSort function.

Note: The_ArrayMultiSort function  uses the accompanying __TestExp () function.

Edited by Malkey
The "here" link linked to this post and not the location of the _ArrayMultiSort function.

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0