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):
Sort Array (2D) ? Topic is solved
-
- Posts: 4412
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: Sort Array (2D) ?
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
}
Re: Sort Array (2D) ?
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:
1483 targets in 26.8(SortByKey_2) & 56.1(SortByKey_3) seconds
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
}
Last edited by BartmanEH on 08 Apr 2021, 15:31, edited 1 time in total.
-
- Posts: 4412
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: Sort Array (2D) ?
Perhaps most of time you deal with semi-sorted arrays, the function with Sort is faster in that case.
-
- Posts: 41
- Joined: 13 Feb 2021, 10:34
Re: Sort Array (2D) ?
swagfag
Can you explain your code:
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
At this point msgbox % todaysschedule
shows
{19:00 "Calendar",11:10 "Mop",18:30 "Vacuum"}
Now when I put in your code:
msgbox is blank
Google search shows nothing that can explain this code to me
Please, what am I doing wrong?
Mike
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 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
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
Google search shows nothing that can explain this code to me
Please, what am I doing wrong?
Mike
Re: Sort Array (2D) ?
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
but if thats what u want, thats what u want:
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-arrayI have thise arrays:
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:At this point msgbox % todaysschedule
shows
{19:00 "Calendar",11:10 "Mop",18:30 "Vacuum"}
Code: Select all
{
19: "00Calendar",
11: "10Mop",
18: "30Vacuum"
}
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
-
- Posts: 41
- Joined: 13 Feb 2021, 10:34
Re: Sort Array (2D) ?
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
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