Sorting strings containing numbers Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
pneumatic
Posts: 338
Joined: 05 Dec 2016, 01:51

Sorting strings containing numbers

Post by pneumatic » 20 Jan 2022, 17:53

Regarding the Sort function, it considers the string "10" to come before "9" or "9 ". This can be problematic when sorting strings containing numbers, eg.

Code: Select all

List := "Folder 8" . "`nFolder 9" . "`nFolder 10" . "`nFolder 11"
Sort , List 
MsgBox , % List
Result:
Folder 10
Folder 11
Folder 8
Folder 9
In Windows file explorer, sorting gives the desired:
Folder 8
Folder 9
Folder 10
Folder 11
But when sorting files, Windows produces the same result as AHK.

It seems possible to workaround by specifying our own custom sort rules by using F parameter. However that seems to require implementing the sort from scratch on a per-character basis, which kind of defeats the purpose of using Sort, and there would probably be edge cases where my implementation would fail. Is there an easier way?

I think the rule I want is that when it compares chars between items it should treat " " or "" as having higher alphabetical order than any number?

https://www.autohotkey.com/docs/commands/Sort.htm wrote:Sort , List , F

"F MyFunction [v1.0.47+]: Uses custom sorting according to the criteria in MyFunction (though sorting takes much longer). Specify the letter "F" followed by optional spaces/tabs followed by the name of a function to be used for comparing any two items in the list. The function must accept two or three parameters. When the function deems the first parameter to be greater than the second, it should return a positive integer; when it deems the two parameters to be equal, it should return 0, "", or nothing; otherwise, it should return a negative integer. If a decimal point is present in the returned value, that part is ignored (i.e. 0.8 is the same as 0). If present, the third parameter receives the offset (in characters) of the second item from the first as seen in the original/unsorted list (see examples). Finally, the function uses the same global settings (e.g. StringCaseSense) as the Sort command that called it."

pneumatic
Posts: 338
Joined: 05 Dec 2016, 01:51

Re: Sorting strings containing numbers  Topic is solved

Post by pneumatic » 20 Jan 2022, 18:18

Hmm this solution by @jeeswg seems to work:
https://www.autohotkey.com/boards/viewtopic.php?f=5&t=63893#p273947 wrote:

Code: Select all

Sort, List, F SortStrCmpLogical

SortStrCmpLogical(vTextA, vTextB, vOffset) ;for use with AHK's Sort command
{
	local
	vRet := DllCall("shlwapi\StrCmpLogicalW", "WStr",vTextA, "WStr",vTextB)
	return vRet ? vRet : -vOffset
}
I'll need to test it some more but it seems to do the trick.

User avatar
Chunjee
Posts: 1419
Joined: 18 Apr 2014, 19:05
Contact:

Re: Sorting strings containing numbers

Post by Chunjee » 12 Mar 2022, 11:36

Another way:

Code: Select all

; requires https://github.com/Chunjee/array.ahk
array := ["Folder 9", "Folder 8", "Folder 11", "Folder 10"]
array.sort(func("fn_digitSort"))
; => ["Folder 8", "Folder 9", "Folder 10", "Folder 11"]


; functions
fn_digitSort(param1, param2)
{
	justNumbers1 := RegExReplace(param1, "\D+", "")
	justNumbers2 := RegExReplace(param2, "\D+", "")
	if (justNumbers1 < justNumbers2) {
		return -1
	}
	if (justNumbers1 > justNumbers2) {
		return 1
	}
	return 0
}
Last edited by Chunjee on 12 Mar 2022, 13:16, edited 1 time in total.

sofista
Posts: 650
Joined: 24 Feb 2020, 13:59
Location: Buenos Aires

Re: Sorting strings containing numbers

Post by sofista » 12 Mar 2022, 12:02

Another take, use a blank space as a delimiter and sort numerically:

Code: Select all

List := "Folder 8" . "`nFolder 9" . "`nFolder 10" . "`nFolder 11"
Sort, List, D%A_Space% N
MsgBox , % List

/* Output:

Folder 8
Folder 9
Folder 10
Folder 11

 */

Post Reply

Return to “Ask for Help (v1)”