Sign in to follow this  
Followers 0
Ozzy

HOW TO sort multi dimensional array

10 posts in this topic

Hi all,

I got a script that load from a site some tables and build an array of about 1000rows and 5 coloumns...

First col contains strings

2nd,3rd,4th,5th cols contains numbers

I what to sort by 2nd coloumns (descendent mode)...

What must I do?

Anyone can help me???

- Ozzy -

Share this post


Link to post
Share on other sites



#3 ·  Posted (edited)

Hi all,

I got a script that load from a site some tables and build an array of about 1000rows and 5 coloumns...

First col contains strings

2nd,3rd,4th,5th cols contains numbers

I what to sort by 2nd coloumns (descendent mode)...

What must I do?

Anyone can help me???

- Ozzy -

The UDF included with AutoIt has a function to sort 1 or 2 dimensional arrays.

Edited by martin

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

It didn't work...

I don't know why but it change the order but with any real order (no ascending neither descending on any coloumn)

That's curious, but not descriptive at all.

And as they say that picture is worth a thousand words. So would you be so nice to run this script below and post a screenshot of array display window for me?

#include <Array.au3>
Global $b[20][5] = [["A 0",-1.5,2.48437,4.3,-3.6],["A 1",3.392,"-2.35306",-5,3], ["A 2",3.061,-4.66,-1.6,-0.863],["A 3",3,-5,-3.7966,-1.77], ["A 4",3,-2.286,-0.68,-1.24],["A 5",-4.8364,-2.8,-2.1339,-1.736], ["A 6",-3.0112,"-3",3.12,-0.43],["A 7",-1,-1.1,3.80852,-1.23828], ["A 8",1.89094,1.6,4.8071,1.81],["A 9",-2,4.23403,3.938,4], ["A 10",1,-4.61771,2.219,0.43934],["A 11",-3.54,-4,3.07,2], ["A 12",3.207,-2.31582,1.7478,-2.208],["A 13",3,3.1219,-4,-4.88], ["A 14",3,1.63,-1.2,2],["A 15",-4.445,1.348,0.0183,-4.5], ["A 16",2.823,-1.563,-2.68481,0.9405],["A 17",2,2.239,2.71174,-1.216], ["A 18",-0.3,0.04,3.9,-4],["A 19",-3.8224,-4.28041,-2,4.1012]]
_ArraySortClib($b, 0, True, 0, 0, 2)
_ArrayDisplay($b, "Sort: Col 2, Num, Descend; on "&@OSVersion&", "&@OSServicePack&", "&@ProcessorArch&", CRT v"&FileGetVersion("msvcrt.dll"))


Func _ArraySortClib(ByRef $Array, $iMode = 1, $fDescend = False, $iStart = 0, $iEnd = 0, $iColumn = 0, $iWidth = 128)
    Local $iArrayDims = UBound($Array, 0)
    If @error Or $iArrayDims > 2 Then Return SetError(1, 0, 0)
    Local $iArraySize = UBound($Array, 1), $iColumnMax = UBound($Array, 2)
    If $iArraySize < 2 Then Return 0
    If $iEnd < 1 Or $iEnd > $iArraySize - 1 Then $iEnd = $iArraySize - 1
    If ($iEnd - $iStart < 2) Then Return SetError(2, 0, 0)
    If $iArrayDims = 2 Then
        If ($iColumnMax - $iColumn < 0) Then Return SetError(2, 0, 0)
    EndIf
    If $iWidth < 1 Then Return SetError(2, 0, 0)
    $iWidth = Ceiling($iWidth / 8) * 8
    Local $sMem, $tSource, $pSource, $i, $j, $iCount, $fNumeric, $fCase, $aRet, $hMsvcrt, $sStrCmp, $tFloatCmp, $pCmp, $tIndexer
    Switch $iMode
        Case 0
            $fNumeric = True
        Case 1
            $fCase = False
        Case 2
            $fCase = True
        Case Else
            Return SetError(2, 0, 0)
    EndSwitch
    ;; initialize sorting proc
    If $fNumeric Then
        $tFloatCmp = DllStructCreate("byte[36]")
        DllStructSetData($tFloatCmp, 1, Binary("0x8B4C24048B542408DD01DC1ADFE0F6C440750D80E441740433C048C333C040C333C0C3"))
        $pCmp = DllStructGetPtr($tFloatCmp)
    Else
        $sStrCmp = "_strcmpi" ;case insensitive
        If $fCase Then $sStrCmp = "strcmp" ;case sensitive
        $aRet = DllCall('kernel32.dll', 'hwnd', 'LoadLibraryA', 'str', 'msvcrt.dll')
        $hMsvcrt = $aRet[0]
        $aRet = DllCall('kernel32.dll', 'ptr', 'GetProcAddress', 'ptr', $hMsvcrt, 'str', $sStrCmp)
        DllCall('kernel32.dll', 'hwnd', 'FreeLibrary', 'hwnd', $hMsvcrt)
        If $aRet[0] = 0 Then Return -1
        $pCmp = $aRet[0]
    EndIf
    ;; initialize memory
    $sMem = ""
    If $fNumeric Then
        For $i = 1 To $iArraySize
            $sMem &= "double;int[4];"
        Next
        $iWidth = 24
    Else
        For $i = 1 To $iArraySize
            $sMem &= "char[" & $iWidth & "];int[4];"
        Next
        $iWidth += 16
    EndIf
    $sMem = StringTrimRight($sMem, 1)
    $tSource = DllStructCreate($sMem)
    ;; fill memory
    If $iArrayDims = 1 Then
        For $i = 0 To $iArraySize - 1
            DllStructSetData($tSource, $i * 2 + 1, $Array[$i])
        Next
    Else
        For $i = 0 To $iArraySize - 1
            DllStructSetData($tSource, $i * 2 + 1, $Array[$i][$iColumn])
        Next
    EndIf
    ;; enumerate elements
    $tIndexer = DllStructCreate("byte[32]")
    DllStructSetData($tIndexer, 1, Binary("0x33C08B7424048B4C2408037424108B5C240C890603F3403BC17CF7C3"))
    DllCall('user32.dll', 'uint', 'CallWindowProc', 'ptr', DllStructGetPtr($tIndexer), 'ptr', DllStructGetPtr($tSource, 2), 'int', $iArraySize, 'int', $iWidth, 'int', 4)
    $pSource = DllStructGetPtr($tSource, $iStart * 2 + 1) ;;pointer to search starting element
    $iCount = $iEnd - $iStart + 1 ;;count of elements to search
    ;;sort
    DllCall('msvcrt.dll', 'none:cdecl', 'qsort', 'ptr', $pSource, 'int', $iCount, 'int', $iWidth, 'ptr', $pCmp)
    ;; read back the result
    Local $aTmp = $Array, $iRef
    If $iArrayDims = 1 Then ; 1D
        If $fDescend Then
            For $i = $iStart To $iEnd
                $iRef = DllStructGetData($tSource, $i * 2 + 2, 2)
                $Array[$iEnd + $iStart - $i] = $aTmp[$iRef]
            Next
        Else ; ascending
            For $i = $iStart To $iEnd
                $iRef = DllStructGetData($tSource, $i * 2 + 2, 2)
                $Array[$i] = $aTmp[$iRef]
            Next
        EndIf
    Else ; 2D
        If $fDescend Then
            For $i = $iStart To $iEnd
                $iRef = DllStructGetData($tSource, $i * 2 + 2, 2)
                For $j = 0 To $iColumnMax - 1
                    $Array[$iEnd + $iStart - $i][$j] = $aTmp[$iRef][$j]
                Next
            Next
        Else ; ascending
            For $i = $iStart To $iEnd
                $iRef = DllStructGetData($tSource, $i * 2 + 2, 2)
                For $j = 0 To $iColumnMax - 1
                    $Array[$i][$j] = $aTmp[$iRef][$j]
                Next
            Next
        EndIf
    EndIf
    Return 1
EndFunc   ;==>_ArraySortClib

"be smart, drink your wine"

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

here you are...

Posted Image

Edited by Ozzy

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

Thanks!

So as I see it works as intented:

"Col 2" is properly sorted using numerical descending order.

But isn't it what you need?

Edited by Siao

"be smart, drink your wine"

Share this post


Link to post
Share on other sites

Thanks!

So as I see it works as intented:

"Col 2" is properly sorted using numerical descending order.

But isn't it what you need?

Looks to me like it's just some confusion about what column 2 means. Maybe Ozzy wanted the second column sorted which is probably column 1.


Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

This version works with 3.2.11.0 Beta, but fails with 3.2.10.0 Prod. I also had to remove some quotes from Siao's data set, because the included UDF does not convert string to number automatically, which throws off the sort.

#include <Array.au3>
Global $b[20][5] = [ _
    ["A 0",-1.5,2.48437,4.3,-3.6],["A 1",3.392,-2.35306,-5,3], ["A 2",3.061,-4.66,-1.6,-0.863], _
    ["A 3",3,-5,-3.7966,-1.77], ["A 4",3,-2.286,-0.68,-1.24],["A 5",-4.8364,-2.8,-2.1339,-1.736], _
    ["A 6",-3.0112,-3,3.12,-0.43],["A 7",-1,-1.1,3.80852,-1.23828], ["A 8",1.89094,1.6,4.8071,1.81], _
    ["A 9",-2,4.23403,3.938,4], ["A 10",1,-4.61771,2.219,0.43934],["A 11",-3.54,-4,3.07,2], _
    ["A 12",3.207,-2.31582,1.7478,-2.208],["A 13",3,3.1219,-4,-4.88], ["A 14",3,1.63,-1.2,2], _
    ["A 15",-4.445,1.348,0.0183,-4.5], ["A 16",2.823,-1.563,-2.68481,0.9405],["A 17",2,2.239,2.71174,-1.216], _
    ["A 18",-0.3,0.04,3.9,-4],["A 19",-3.8224,-4.28041,-2,4.1012]]
_ArrayDisplay($b, "Unsorted")
_ArraySort($b, 1, 0, 0, 1)
_ArrayDisplay($b, "Sorted: 2nd Col, Num, Descend")

:)


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

Thanks!

So as I see it works as intented:

"Col 2" is properly sorted using numerical descending order.

But isn't it what you need?

The issue was my fault...

My matrix wasn't "wellformed"

Now it work perfectly!

Thanks and great work with that func!!!

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