Sort Array (2D) ? Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
BartmanEH
Posts: 23
Joined: 01 Apr 2021, 15:48

Re: Sort Array (2D) ?

08 Apr 2021, 12:03

which approach is 'better'? the fixed version immediately above using recursion (if not recursion, at least calling itself from within itself) or the proposed alternate posted last night using built-in Sort (which I found elegant)?
The proposed alternate with Sort has been working well for me, if not expensive (slow):
image.png
image.png (35.47 KiB) Viewed 643 times
teadrinker
Posts: 4412
Joined: 29 Mar 2015, 09:41
Contact:

Re: Sort Array (2D) ?

08 Apr 2021, 13:12

BartmanEH wrote: which approach is 'better'?
Fixed version uses one of the fastest algorithms. You can compare them:

Code: Select all

SetBatchLines, -1
Loop 2 {
   i := A_Index
   arr := []
   Loop 10000 {
      Random, rand, 0, 10000
      arr.Push({myKey: rand})
   }

   Loop 2 { ; the second time the already sorted array is sorted again
      start := A_TickCount
      arr := SortByKey%i%(arr, "myKey")
      MsgBox, % A_TickCount - start
   }
}

SortByKey1(arr, key, reverse := false) {
   ArrMin := [], ArrMax := []
   Random, pivot, 1, arr.Count()
   for k, v in arr {
      if (k = pivot)
         continue
      
      array := (!reverse ? arr[k, key] < arr[pivot, key] : arr[k, key] > arr[pivot, key]) ? "ArrMin" : "ArrMax"
      %array%.Push(v)
   }
   for k, v in ["ArrMin", "ArrMax"]
      (%v%.Length() > 1 && %v% := SortByKey1(%v%, key, reverse))

   ArrMin.Push(arr[pivot], ArrMax*)
   Return ArrMin
}

SortByKey2(arr, key, reverse := false, numeric := true) {
   static ch := Chr(1)
   newArr := [], obj := arr.Clone()
   for k, v in obj
      keys .= (A_Index = 1 ? "" : ch) . v[key]
   Sort, keys, % (numeric ? "N" : "") . (reverse ? " R" : "") . " D" . ch
   Loop, parse, keys, %ch%
   {
      for k, v in obj {
         if (A_LoopField = v[key]) {
            newArr.Push(v), obj.Delete(k)
            break
         }
      }
   }
   Return newArr
}
BartmanEH
Posts: 23
Joined: 01 Apr 2021, 15:48

Re: Sort Array (2D) ?

08 Apr 2021, 14:50

I haven't played with your comparison script yet but my own results show that the function with Sort is about twice as fast as the fixed one:

Code: Select all

SortByKey_2(arr, key, reverse := false, numeric := true) {    ;alternate suggestion by 'teadrinker' to avoid 'recursion limit exceeded' exception
   static ch := Chr(1)
   newArr := [], obj := arr.Clone()
   for k, v in obj
      keys .= (A_Index = 1 ? "" : ch) . v[key]
   Sort, keys, % (numeric ? "N" : "") . (reverse ? " R" : "") . " D" . ch
   Loop, parse, keys, %ch%
   {
      for k, v in obj {
         if (A_LoopField = v[key]) {
            newArr.Push(v), obj.Delete(k)
            break
         }
      }
   }
   Return newArr
}

Code: Select all

SortByKey_3(arr, key, reverse := false) {   ;modified original approach by 'teadrinker' to avoid 'recursion limit exceeded' exception
   ArrMin := [], ArrMax := []
   Random, pivot, 1, arr.Count()
   for k, v in arr {
      if (k = pivot)
         continue

      array := (!reverse ? arr[k, key] < arr[pivot, key] : arr[k, key] > arr[pivot, key]) ? "ArrMin" : "ArrMax"
      %array%.Push(v)
   }
   for k, v in ["ArrMin", "ArrMax"]
      (%v%.Length() > 1 && %v% := SortByKey_3(%v%, key, reverse))

   ArrMin.Push(arr[pivot], ArrMax*)
   Return ArrMin
}
1483 targets in 26.8(SortByKey_2) & 56.1(SortByKey_3) seconds
Last edited by BartmanEH on 08 Apr 2021, 15:31, edited 1 time in total.
teadrinker
Posts: 4412
Joined: 29 Mar 2015, 09:41
Contact:

Re: Sort Array (2D) ?

08 Apr 2021, 15:12

Perhaps most of time you deal with semi-sorted arrays, the function with Sort is faster in that case.
mstrauss2021
Posts: 41
Joined: 13 Feb 2021, 10:34

Re: Sort Array (2D) ?

11 Mar 2023, 16:39

swagfag

Can you explain your code:

Code: Select all

myArray := {2:00 "Quick",4: "Brown",3: "Fox",1: "Jumps"}

For i, x In myArray
	myResult .= i " " x "`n"
MsgBox % myResult
I can get this to work, but when I apply it to my code msgbox is blank. I am so frustrated.

I can tell you I had to put my array into a string matching your example of myarray but that didnt work. Here is my code

I have thise arrays:
hour1 = 19
hour2 = 11
hour3 = 18
min1 = 00
min2 = 10
min3 - 30
maintitle1 = calendar
maintitle2 = mop
maintitle3 = vacuum

I also have a variable itemcount = 3 to use for loops

to get them in a string (with the necessary commas, braces and quotes I did this

Code: Select all

loop, %itemcount%                               ; Put array in a different array and add quotes (chr(34), colons and commas
{
    tempschedule%A_Index% := hour%A_Index% ":" min%A_Index% A_Tab chr(34) maintitle%A_Index% chr(34) ","
}

loop, %itemcount%   ; put array in variable
{
    todaysschedule := todaysschedule tempschedule%A_Index%
}

StringTrimRight, todaysschedule, todaysschedule, 1      ; remove last comma from variable

todaysschedule := "`{" todaysschedule "`}"        ;  add { and } to beginning and end of string
At this point msgbox % todaysschedule
shows
{19:00 "Calendar",11:10 "Mop",18:30 "Vacuum"}

Now when I put in your code:

Code: Select all

For i, x In todaysschedule
	myResult .= i " " x "`n"
MsgBox % myResult
msgbox is blank

Google search shows nothing that can explain this code to me
Please, what am I doing wrong?

Mike
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Sort Array (2D) ?

11 Mar 2023, 17:03

what ure doing wrong is thinking a String (that just so happens to contain something vaguely resembling the way u would declare and populate an Object in the script's source) is the same thing as an actual Object declared and populated in the script's source. its like drawing a computer on a piece of paper with ur crayons and acting all surprised when u find out cant actually send an email to ur grandma with it
I have thise arrays:
no, what u have is a bunch of free floating variables with funny numbers slapped on their ends. or what v1 would consider, a pseudo-array
At this point msgbox % todaysschedule
shows
{19:00 "Calendar",11:10 "Mop",18:30 "Vacuum"}
ok, having such an Object makes zero sense to me. uve got hours as the keys, mapped to strings which end up being the concatenation of the minutes and some random word, ie:

Code: Select all

{
	19: "00Calendar",
	11: "10Mop",
	18: "30Vacuum"
}
but if thats what u want, thats what u want:

Code: Select all

hour1 = 19
hour2 = 11
hour3 = 18
min1 = 00
min2 = 10
min3 = 30
maintitle1 = calendar
maintitle2 = mop
maintitle3 = vacuum
itemcount = 3

todaysschedule := {}
loop, %itemcount%                               ; Put array in a different array and add quotes (chr(34), colons and commas
{
	todaysschedule[hour%A_Index%] := min%A_Index% maintitle%A_Index%
}

For i, x In todaysschedule
	myResult .= i " " x "`n"
MsgBox % myResult
mstrauss2021
Posts: 41
Joined: 13 Feb 2021, 10:34

Re: Sort Array (2D) ?

11 Mar 2023, 18:11

Wow,

Thanks for this fix works perfectly.

I have to say I have been programming with AHK for 3 years now and with arrays only for about 6-months and I just don't understand what this code is doing.

At least I have something to play with for awhile to figure this out.

Thanks again swagfag

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: dra3th, Mateusz53, Rohwedder, Spawnova and 268 guests