Jump to content

Recommended Posts

Posted (edited)

Currently only works with 1d arrays, ah well.

Explanation: Lets take the example numbers: 4, 3, 11, 19, 35, 41, 73, 43, 81, 72, 87, 11. I need to know what order the numbers should be in, in order to rank them (for anyone interested, its for spearmans rank). This returns a list of indexs, in order.

#include<array.au3>

Local $aArray[12] = [4, 3, 11, 19, 35, 41, 73, 43, 81, 72, 87, 114]

$temp = _ArrayGetOrder ($aArray)
MsgBox (0, "Result", $temp)

; #FUNCTION# ====================================================================================================================
; Name...........: _ArrayGetOrder
; Description ...: Returns a list of the indexes ordered by their value
; Syntax.........: _ArrayGetOrder ($aArray[, $iStart = 0[, $iEnd = 0[, $nRetType = 0]]])
; Parameters ....: $avArray      - Array to search
;                  $iStart       - [optional] Index of array to start searching at
;                  $iEnd         - [optional] Index of array to stop searching at
;                  $nRetType     - [optional] If 1, will return An Array showing the indexs of the array ordered. (zero based)
; Return values .: Success - the list as a string ("," comma seperated.)
;                  Failure - -1, sets @error:
;                  |1 - $avArray is not an array
;                  |2 - $iStart is greater than $iEnd
;                  |3 - $avArray is not a 1 dimensional array
;                  |4 - Value is not of numeric type. @Extended holds the index
; Author ........: Mat
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; Yes
; ===============================================================================================================================

Func _ArrayGetOrder ($aArray, $iStart = 0, $iEnd = 0, $nRetType = 0)
    If Not IsArray($aArray) Then Return SetError(1, 0, -1)
    If UBound($aArray, 0) <> 1 Then Return SetError(3, 0, -1)

    Local $iUBound = UBound($aArray) - 1

    ; Bounds checking
    If $iEnd < 1 Or $iEnd > $iUBound Then $iEnd = $iUBound
    If $iStart < 0 Then $iStart = 0
    If $iStart > $iEnd Then Return SetError(2, 0, -1)

   Local $temp = ""

   For $i = $iStart to $iEnd
      $iMaxIndex = 0
      If Not IsNumber ($aArray[$i]) Then Return SetError (4, $i, -1)
        For $x = $iStart To $iEnd
            If $aArray[$iMaxIndex] < $aArray[$x] Then $iMaxIndex = $x
        Next
      $temp &= "," & $iMaxIndex
      $aArray[$iMaxIndex] = 0
   Next
   $temp = StringTrimLeft ($temp, 1)
   If $nRetType = 0 then return $temp
   Return StringSplit ($temp, ",", 2)
EndFunc ; ==> _ArrayGetOrder

I better explain exactly what I mean by 'ranking':

Posted Image

Yellow is what I call the ranking, and s what it returned by this function. Green is what would be returned by _ArraySort.

Mat

Edited by Mat
  • Moderators
Posted

Ok, have to ask.

1. Why not use _ArraySort()?

2. Why did you turn my integer array into a string?

3. What if my string array actually has a comma in it already?

There's more, but I'll stop here.

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.

Posted

No, its not sorting its returning the indexs. The example should return: 11,10,8,6,9,7,5,4,3,2,0,1

From that I know that I could sort it by putting the values in that order, but I don't want to! Its for ranking not sorting. I know that the lowest value can be found in index 11 (114) see?

I don't have to turn it to a string, but its an option when $nretType = 0

If your string array is entered, you'll get @Error: 4 @Extended: $i Return: -1. It's not supposed to work with strings.

I think you misinterpreted what I wanted to do. This is one step short of sorting, BUT the code is similar (ish).

Mat

  • 1 year later...
Posted

I looked a loong time for something like this

Using your method (simple but brilliant) directly in the script

Local $aArray[12] = [4, 3, 11, 19, 35, 41, 73, 43, 81, 72, 87, 114]

Dim $temp[12]
For $i = 0 to 11
    $iMaxIndex = 0
    For $x = 0 To 11
        If $aArray[$iMaxIndex] < $aArray[$x] Then $iMaxIndex = $x
        Next
    $temp[$i] = $iMaxIndex
    $aArray[$iMaxIndex] = 0
Next
_ArrayDisplay($temp)

Now I can create 2 different ways of ranking the same item, and display this in one single listview

Thanks A LOT !!

and I applaud a lot too :)

Posted (edited)

Looking at this post just made me wonder why you didn't impliment it for 2D arrays. You could rank values by column or by row index. Just a thought.

Edit: Oops I see this is just the current version.

Another possibility would be to use different sorting criteria, or even better: use several sorting criteria in a specified order, defined by the user. The option to throw exceptions such as to ignore values containing certain digits or repeat characters within a string (using a regexp as a parameter) would be quite cool. I admit the possibilities are quite overwhelming, but defining a flexible system seems like an intertesting challenge. Perhaps it's rehashing stuff, but I like the concept.

Edited by czardas
Posted

I only wrote it for a very specific purpose for which it worked well, so I don't really have any intention of doing any work on it. It's not a particularly complex system so I see no reason why other people who do want strange sorting mechanisms can't just do it themselves :) Unless I just implement a callback function as a last parameter...

Mat

Posted (edited)

I only wrote it for a very specific purpose for which it worked well, so I don't really have any intention of doing any work on it. It's not a particularly complex system so I see no reason why other people who do want strange sorting mechanisms can't just do it themselves :) Unless I just implement a callback function as a last parameter...

Mat

I see your point. I just though of it because it's similar to something I'm working on ATM: that is having an array with static elements and a number of algorithms to sort the elements into subsets (reordered as and when required). The subsets are stored as arrays of index numbers in the same way. It's part of a regional and generic search priority filter. :) Edited by czardas
Posted

that is having an array with static elements and a number of algorithms to sort the elements into subsets (reordered as and when required)

Exactly... what Mat called 'strange sorting mechanisms'

Though I prefer the precision he gave in the previous post : 'Its for ranking not sorting' :)

OK it's not particularly complex and it looks simple (when done !) but it's very useful and should be integrated to the _Array UDF

Posted (edited)

Exactly... what Mat called 'strange sorting mechanisms'

Though I prefer the precision he gave in the previous post : 'Its for ranking not sorting' :)

Well I was refering to something similar - arranging subsets according to ranked priority. That's also some kind of ranking. :) Edited by czardas
Posted

I doubt it is useful at all. I'm the only person whos needed it in two years :)

I better explain exactly what I mean by 'ranking':

Posted Image

Yellow is what I call the ranking, and s what it returned by this function. Green is what would be returned by _ArraySort. I'll add this pic to the first post as well.

Mat

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
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...