Hi everyone,
with javascript it's possible to sort this list:
2
File 20.png
File 3.tmp
1
10
Test - 9 - fjg
1234567
File 9.abc
Test - 2 - zgrg
Test - 1 - gshsgh
Test - 10 - tjfmn
Test - 11 - mnulk
File 1.ahk
File 2
Test - 15 - bnn
1234568
Test - 15 - jfgjgfm
into this:
1
2
10
1234567
1234568
File 1.ahk
File 2
File 3.tmp
File 9.abc
File 20.png
Test - 1 - gshsgh
Test - 2 - zgrg
Test - 9 - fjg
Test - 10 - tjfmn
Test - 11 - mnulk
Test - 15 - bnn
Test - 15 - jfgjgfm
How can I do the same with AHK? Thanks.
Natural sort Topic is solved
Re: Natural sort
Try:
Code: Select all
text:="
(
2
File 20.png
File 3.tmp
1
10
Test - 9 - fjg
1234567
File 9.abc
Test - 2 - zgrg
Test - 1 - gshsgh
Test - 10 - tjfmn
Test - 11 - mnulk
File 1.ahk
File 2
Test - 15 - bnn
1234568
Test - 15 - jfgjgfm
)"
MsgBox % nsort(text)
nSort(s){
Sort, s
If p:=RegExMatch(s,"`a)\R[^\d\R]"){
a:=SubStr(s,1,p-1),b:=SubStr(s,p)
Sort, a, N
s:= a b
}
return s
}
Re: Natural sort
Hi, HotKeyIt, thanks for the help.
So I tried but I get this:
1
2
10
1234567
1234568
File 1.ahk
File 2
File 20.png
File 3.tmp
File 9.abc
Test - 1 - gshsgh
Test - 10 - tjfmn
Test - 11 - mnulk
Test - 15 - bnn
Test - 15 - jfgjgfm
Test - 2 - zgrg
Test - 9 - fjg
The numbers are ok but the strings with numbers in the middle still get mixed up.
This is quite annoying. I couldn't find an answer even in the old forums. Why is this stuff not a feature?
Re: Natural sort
That's not sorting numerically within the same group of items that start with the same non-numeric characters as was shown in the desired output:
Seems like a pretty complicated sort. I started something and then saw how involved it was going to be.
Seems like a pretty complicated sort. I started something and then saw how involved it was going to be.
Re: Natural sort
Found on the old forums: https://autohotkey.com/board/topic/32820-natural-sorting/
Following can handle up to 100 numbers in string:
Following can handle up to 100 numbers in string:
Code: Select all
s:="
(
2
File 20.png
File 3.tmp
1
10
Test - 9 - fjg
1234567
File 9.abc
Test - 2 - zgrg
Test - 1 - gshsgh
Test - 10 - tjfmn
Test - 11 - mnulk
File 1.ahk
File 2
Test - 15 - bnn
1234568
Test - 15 - jfgjgfm
)"
Sort, s,F cmp
MsgBox % s
cmp(x,y) {
RegExMatch(x,"(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(.*)",x)
,RegExMatch(y,"(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(\D*)(\d*)(.*)",y)
Loop 201
If (x%A_Index% != y%A_Index%)
Return 2*(x%A_Index%>y%A_Index%) - 1
}
Re: Natural sort
I guess it is, but I think it's a pretty important one. I hoped someone had already worked it out years ago. Closest thing I found is here (credits to Laszlo):
Code: Select all
dfhfdahad := Clipboard
MsgBox % Sort(dfhfdahad)
Sort(x, delim="`n") {
x := x . "`n"
IfEqual delim,, SetEnv delim, `n
Sort x, D%delim%
Loop Parse, x, %delim%
{
If (p = PreText(A_LoopField))
y = %y%%delim%%A_LoopField%
Else {
Sort y, % "N D" delim " P" StrLen(p)+1
z = %z%%y%%delim%
p := PreText(A_LoopField)
y = %A_LoopField%
}
}
StringTrimLeft z, z, 1
Return z
}
PreText(x) {
Loop Parse, x, 0123456789
Return A_LoopField
}
1
2
10
1234567
1234568
File 1.ahk
File 2
File 3.tmp
File 9.abc
File 20.png
Test - 1 - gshsgh
Test - 2 - zgrg
Test - 9 - fjg
Test - 10 - tjfmn
Test - 11 - mnulk
Test - 15 - jfgjgfm <----
Test - 15 - bnn <----
Re: Natural sort
Thanks, HotKeyIt, for pointing out that thread. How about this one by animeaime in the next page:HotKeyIt wrote: ↑02 Apr 2020, 16:50Found on the old forums: https://autohotkey.com/board/topic/32820-natural-sorting/
Following can handle up to 100 numbers in string:
...
It seems this one has no number limitations and it seems to work but I've no idea if it's reliable.I was showed this thread and it is exactly what I was looking for. I tweaked Laszlo's solution from a few posts ago because I need to allow sorting regardless how many numbers are in the string - looking for performance feedback.Code: Select all
LogicalSort(x,y,offset) { static RegEx := "S)(\D*)(\d*)(.*)" Loop { RegExMatch(x, RegEx, x) RegExMatch(y, RegEx, y) if (x1 != y1) return x1 < y1 ? -1 : 1 if (x2 != y2) return x2 < y2 ? -1 : 1 if (x3 = "" || y3 = "") break x := x3 y := y3 } if (x3 != "") { ;x is "longer" return 1 } else if (y3 != "") { ;y is "longer" return -1 } else { ;equal - maintain original order (stable) return -offset } }
Re: Natural sort
I have missed some posts, sorry!
I think I found the best solution here, courtesy of jeeswg:
If not a feature of AHK, this should at least be in the documentation as an example or something.
Thanks, to boiler and HotKeyIt!
I think I found the best solution here, courtesy of jeeswg:
jeeswg wrote: ↑23 Apr 2019, 08:32- You can make use of the StrCmpLogicalW function, to sort items like Explorer sorts file names.
- Note: there is no StrCmpLogicalA or ANSI equivalent function, however, by using 'WStr', you can use the function with ANSI versions of AutoHotkey.
- WStr converts ANSI strings into Unicode strings in ANSI versions of AHK. WStr leaves Unicode strings unchanged in Unicode versions of AHK.Code: Select all
q:: ;sort using StrCmpLogicalW List := " ( Chapter 3 Chapter 1 Chapter 999 Chapter 10 Chapter -69 Chapter 2 )" Sort, List, F SortStrCmpLogical MsgBox, % List return SortStrCmpLogical(vTextA, vTextB, vOffset) ;for use with AHK's Sort command { local vRet := DllCall("shlwapi\StrCmpLogicalW", "WStr",vTextA, "WStr",vTextB) return vRet ? vRet : -vOffset }
If not a feature of AHK, this should at least be in the documentation as an example or something.
Thanks, to boiler and HotKeyIt!
Re: Natural sort Topic is solved
You use this function, StrCmpLogical and use sort with F MyFunction option, example,
Cheers.
Code: Select all
logical_sort(byref str) {
sort str, % "f logical_cmp"
}
logical_cmp(a,b, o) {
return dllcall("Shlwapi.dll\StrCmpLogicalW", "wstr", a, "wstr", b, "int")
}
v2
Re: Natural sort
Hi, Helgef! Thank you for your answer.
I have a couple of things I'd like to ask you. What's the difference, if any, between StrCmpLogicalW', 'ptr' and StrCmpLogicalW", "wstr" ? Also is it possible to use this function to sort the elements of an array?
Thanks.
I have a couple of things I'd like to ask you. What's the difference, if any, between StrCmpLogicalW', 'ptr' and StrCmpLogicalW", "wstr" ? Also is it possible to use this function to sort the elements of an array?
Thanks.
Re: Natural sort
You have to use wstr for ANSI compatibility, when you use wstr(or astr orstr) AHK will also update the string's length after the call, which is a little wasteful since we know it doesn't change. By just passing 'ptr', &a you avoid that. For v2 there is no ansi version so ptr is OK. You can use ptr for v1 unicode build too, if you like.
Sort doesn't support sorting arrays, there are custom sorting functions for arrays, you can probably find one which supports custom sort functions, then use the logical_cmp. function.
Cheers.
Edit, my posts in this thread looks a bit weird, but when I posted them, this post hadn't been approved by a moderator, so I couldn't see it.
Sort doesn't support sorting arrays, there are custom sorting functions for arrays, you can probably find one which supports custom sort functions, then use the logical_cmp. function.
Cheers.
Edit, my posts in this thread looks a bit weird, but when I posted them, this post hadn't been approved by a moderator, so I couldn't see it.
Re: Natural sort
You can do this way:
Code: Select all
Array := ["2","File 20.png","File 3.tmp","1","10","Test - 9 - fjg","1234567","File 9.abc","Test - 2 - zgrg","Test - 1 - gshsgh","Test - 20 - tjfmn","Test - 11 - mnulk","File 1.ahk","File 2","Test - 15 - bnn","1234568","Test - 15 - jfgjgfm"]
for k,v in Array
str .= str ? "`n" v : v
sort str, % "f logical_cmp"
Array := StrSplit(str, "`n" )
ExitApp
logical_cmp(a,b, o) {
return dllcall("Shlwapi.dll\StrCmpLogicalW", "wstr", a, "wstr", b, "int")
}
____________________________________________________________________________
Windows 10 Pro 64 bit - Autohotkey v1.1.30.01 64-bit Unicode
Windows 10 Pro 64 bit - Autohotkey v1.1.30.01 64-bit Unicode
Re: Artificial sort
Javascript default array sort sorts your list into the following:
Code: Select all
var array = ["2","File 20.png","File 3.tmp","1","10","Test - 9 - fjg","1234567","File 9.abc","Test - 2 - zgrg","Test - 1 - gshsgh","Test - 20 - tjfmn","Test - 11 - mnulk","File 1.ahk","File 2","Test - 15 - bnn","1234568","Test - 15 - jfgjgfm"]
console.log(array.sort())
/*
[ '1',
'10',
'1234567',
'1234568',
'2',
'File 1.ahk',
'File 2',
'File 20.png',
'File 3.tmp',
'File 9.abc',
'Test - 1 - gshsgh',
'Test - 11 - mnulk',
'Test - 15 - bnn',
'Test - 15 - jfgjgfm',
'Test - 2 - zgrg',
'Test - 20 - tjfmn',
'Test - 9 - fjg' ]
*/
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
The time and space complexity of the sort cannot be guaranteed as it depends on the implementation.
Re: Artificial sort
I never talked about default. Javascript can do natural sort perfectly well if you use Intl.Collator. I have code that does that.
https://stackoverflow.com/questions/2802341/javascript-natural-sort-of-alphanumerical-strings/38641281
https developer.mozilla.org /en-US/docs/Web/JavaScript/Reference/Global_Objects/Collator
Nope. Natural sort is what it's called.
https en.wikipedia.org /wiki/Natural_sort_order
Re: Natural sort
I want this Intl.Collator for ahk then