Jump to content
Sign in to follow this  
DirtDBaK

Sorting a multi-dim array -Almost have it figured out!

Recommended Posts

DirtDBaK

Heres how i need it too work:

[9][105]

[4][7]

[3][5]

after calling the sort function for this array it would return this:

[3][5]

[4][7]

[9][103]

The second column number is important to stay with the first..

The way I can do it now is like so with a 1 dim array

[9|15]

[4|14]

[3|9]

[7|10]

But results aren't right

they go like this

[7|10]

[3|9]

[9|15]

[4|14]

It still will pick out the top 15 values, but there not sorted correctly...

Hope that clears this up a little...

Thanks!

Edited by DBak

[center][/center]

Share this post


Link to post
Share on other sites
Fossil Rock

PsaltyDS helped me with this ... see if you can figure it our for your needs.

#include<Array.au3>

Const $title = "My Documents"
Const $CID = 0x00000001
Send("#r")
WinWaitActive("Run")
Sleep(500)
Send($title)
Sleep(500)
Send("{Enter}")
WinWaitActive($title)
Sleep(500)
$RowCount = ControlListView($title, "", $CID, "GetItemCount")
$ColCount = ControlListView($title, "", $CID, "GetSubItemCount")

Dim $aListView[$RowCount][$ColCount]
For $row = 0 To $RowCount - 1
    For $col = 0 To $ColCount - 1
        $aListView[$row][$col] = ControlListView($title, "", $CID, "GetText", $row, $col)
    Next
Next

$ColOfInterest = 2 ; Col number of Type field

$aResults = _ArrayUnique2D($aListView, $ColOfInterest)
If Not @error Then
    _ArrayDisplay($aResults, "Results, Col: " & $ColOfInterest)
Else
    MsgBox(16, "Error", "_ArrayUnique2D() returned @error = " & @error)
EndIf


; =========================================================================
; Function _ArrayUnique2D()
;   Return 1D array of unique items from selected column in 2D array.
;   Call with _ArrayUnique2D($aInput [, $ColNum]) where:
;     $aInput = 2D array to search
;     $ColNum (optional) = 0-based column to search on
;   Returns a 1D array of unique values with [0] = count
;   On failure, returns non-zero @error
; =========================================================================
Func _ArrayUnique2D($aInput, $ColNum = 0)
    If Not IsArray($aInput) Then Return SetError(1, 0, "") ; Input is not an array
    If UBound($aInput, 0) <> 2 Then Return SetError(2, 0, "") ; Input is not 2D array
    If $ColNum > UBound($aInput, 2) - 1 Then Return SetError(3, 0, "") ; Search column is too high
    Local $aReturn[1], $i, $r
    For $i = 0 To UBound($aInput) - 1
        For $r = 0 To UBound($aReturn) - 1
            If $aInput[$i][$ColNum] = $aReturn[$r] Then ContinueLoop 2
        Next
        _ArrayAdd($aReturn, $aInput[$i][$ColNum])
    Next
    $aReturn[0] = UBound($aReturn) - 1
    Return $aReturn
EndFunc   ;==>_ArrayUnique2D

Agreement is not necessary - thinking for one's self is!

My-Colors.jpg

cuniform2.gif

Share this post


Link to post
Share on other sites
DirtDBaK

Thanks!

ow do i make this Decending?

Edited by DBak

[center][/center]

Share this post


Link to post
Share on other sites
Fossil Rock

It was for my purpose, you'll have to modify it for yours.


Agreement is not necessary - thinking for one's self is!

My-Colors.jpg

cuniform2.gif

Share this post


Link to post
Share on other sites
-Ultima-

@DBak: If speed isn't an issue, you can simply copy the column you want out into a new 1D array, sort that array, then copy the sorted contents back into the 2D array. If speed is an issue, you're going to have to modify the end of the __ArrayQSort2() function in Array.au3 where it swaps contents.

If you decide to take the latter route, then...

For $x = 0 To $d2
                $t = $array[$L][$x]
                $array[$L][$x] = $array[$R][$x]
                $array[$R][$x] = $t
            Next

needs to be changed to

$t = $array[$L][$sortIdx]
            $array[$L][$sortIdx] = $array[$R][$sortIdx]
            $array[$R][$sortIdx] = $t

Beware that this (obviously) will affect all scripts that rely on _ArraySort() for sorting 2D arrays like it normally does, though. I guess you can also make a copy of the _ArraySort() function and use/modify that copy instead of modifying Array.au3 directly, but whatever; I'll stop being Captain Obvious now ;D

Edited by -Ultima-

[ WinINet.au3 | Array.au3 (Optimized) | _UnixTimeParse() ]

Share this post


Link to post
Share on other sites
PsaltyDS

So heres the deal...

I have a x*2 array

[1][2]

[3][4]

[2][787]

[X][X]

I know that the _ArraySort can sort this array decending, but can it sort only the first column, and leave the second column unsorted? I don't know if i'm just having a stupid moment but i read over the help file and wasn't to sure... Any ideas? Thanks!

The _ArraySort() function in the Array.au3 UDF has been updated to handle 2D arrays. So it now has parameters to which index to sort on (0-based so the second index is 1). Demo:

#include <array.au3>

Dim $avArray[5][2] = [[1,2], ['a','b'], [3,4], [2,787], ['X','Y']]
_ArrayDisplay($avArray, "Debug: $avArray Before")

_ArraySort($avArray, 0, 0, 0, 2, 1)
_ArrayDisplay($avArray, "Debug: $avArray After")

<_<


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
-Ultima-

but can it sort only the first column, and leave the second column unsorted?

I think he only wants it to sort one column, but have it not touch the other :) _ArraySort() will move all other columns around in sync with the sort index (which doesn't sound like what he wants). Unless he was expecting _ArraySort() to sort each column one by one...? In that case, it doesn't do that, and yes, using _ArraySort() would work fine as is <_< Edited by -Ultima-

[ WinINet.au3 | Array.au3 (Optimized) | _UnixTimeParse() ]

Share this post


Link to post
Share on other sites
PsaltyDS

I think he only wants it to sort one column, but have it not touch the other :) _ArraySort() will move all other columns around in sync with the sort index (which doesn't sound like what he wants). Unless he was expecting _ArraySort() to sort each column one by one...? In that case, it doesn't do that, and yes, using _ArraySort() would work fine as is <_<

Oops. I think you're right. Scanned it too fast to understand the question properly.

:">


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
SmOke_N

IMO, this request destroys the reason to even have a 2D array, you're better off just creating two arrays separately as the information would never be true from one dimension to the other.


Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites
DirtDBaK

The solution from Fossil rock either isn't working correctly, or i don't know how to use it, its always out of order... If i post source it wont work because it takes a certain file for this to read

maybe I'll try to edit it so that you can see whats going on...


[center][/center]

Share this post


Link to post
Share on other sites
-Ultima-

Have you actually tested the example code that PsaltyDS posted? _ArraySort() already *does* support 2D arrays, and it does move the corresponding entries in the same row in sync...


[ WinINet.au3 | Array.au3 (Optimized) | _UnixTimeParse() ]

Share this post


Link to post
Share on other sites
DirtDBaK

yes i tried it and it doesn't work like i need it too, gives me the same odd results as the sort w/ a pipeline...

thanks!


[center][/center]

Share this post


Link to post
Share on other sites
-Ultima-

#include <array.au3>

Dim $avArray[4][2] = [[9,15], [4,14], [3,9], [7,10]]
_ArrayDisplay($avArray, "Debug: $avArray Before")

_ArraySort($avArray, 0, 0, 0, 2, 0)
_ArrayDisplay($avArray, "Debug: $avArray Sorted (Col 0, Ascending)")

_ArraySort($avArray, 1, 0, 0, 2, 0)
_ArrayDisplay($avArray, "Debug: $avArray Sorted (Col 0, Descending)")

_ArraySort($avArray, 0, 0, 0, 2, 1)
_ArrayDisplay($avArray, "Debug: $avArray Sorted (Col 1, Ascending)")

_ArraySort($avArray, 1, 0, 0, 2, 1)
_ArrayDisplay($avArray, "Debug: $avArray Sorted (Col 0, Descending)")

Not sure what to say, other than that _ArraySort() is working perfectly and as expected here...

It's not really clear (to me) how you're using some 1D array to represent 2 columns of numbers... Are you actually storing pipe-delimited strings of numbers in a 1D array and sorting that array? If so, then weird sorting behavior is to be expected, since it's using an alphanumeric sort in that case rather than a plain numeric sort (though I can't really explain the output you're seeing from sorting that 1D array; I can't really reproduce it either, whatever method I've tried). It really would help if you actually posted some snippets of code. If it's reading the array out of some file, then just reproduce the array manually (or at least a sample of it large enough for us to test).

Edited by -Ultima-

[ WinINet.au3 | Array.au3 (Optimized) | _UnixTimeParse() ]

Share this post


Link to post
Share on other sites
DirtDBaK

Ill try to mod the code so it will work on your computer to show you what is happening... I knew the pipeline was going to cause a problem, but i just wasn't sure what else to do... I didnt think the 1D was a great idea, but it somewhat works... As for the 2D I don't know... I'll definatly try to get some source on here...


[center][/center]

Share this post


Link to post
Share on other sites
PsaltyDS

16 posts into this thread, and now we might see some code.

I think we are learning something here...

... <_<

... :)

... :P

<hear the crickets chirpping?>

:)


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

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  

×