RosettaCodeData/Task/Natural-sorting/11l/natural-sorting.11l
2023-07-01 13:44:08 -04:00

109 lines
2.6 KiB
Text
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

T.enum Kind
STRING
NUMBER
T KeyItem
Kind kind
String s
Int num
F natOrderKey(=s)
// Remove leading and trailing white spaces.
s = s.trim(( , "\t", "\r", "\n"))
// Make all whitespace characters equivalent and remove adjacent spaces.
s = s.replace(re:\s+, )
// Switch to lower case.
s = s.lowercase()
// Remove leading "the ".
I s.starts_with(the ) & s.len > 4
s = s[4..]
// Split into fields.
[KeyItem] result
V idx = 0
L idx < s.len
V e = idx
L e < s.len & !s[e].is_digit()
e++
I e > idx
V ki = KeyItem()
ki.kind = Kind.STRING
ki.s = s[idx .< e]
result.append(ki)
idx = e
L e < s.len & s[e].is_digit()
e++
I e > idx
V ki = KeyItem()
ki.kind = Kind.NUMBER
ki.num = Int(s[idx .< e])
result.append(ki)
idx = e
R result
F scmp(s1, s2)
I s1 < s2 {R -1}
I s1 > s2 {R 1}
R 0
F naturalCmp(String sa, String sb)
V a = natOrderKey(sa)
V b = natOrderKey(sb)
L(i) 0 .< min(a.len, b.len)
V ai = a[i]
V bi = b[i]
I ai.kind == bi.kind
V result = I ai.kind == STRING {scmp(ai.s, bi.s)} E ai.num - bi.num
I result != 0
R result
E
R I ai.kind == STRING {1} E -1
R I a.len < b.len {-1} E (I a.len == b.len {0} E 1)
F test(title, list)
print(title)
print(sorted(list, key' cmp_to_key(naturalCmp)).map(s -> 's').join("\n"))
print()
test(Ignoring leading spaces.,
[ignore leading spaces: 2-2,
ignore leading spaces: 2-1,
ignore leading spaces: 2+0,
ignore leading spaces: 2+1])
test(Ignoring multiple adjacent spaces (MAS).,
[ignore MAS spaces: 2-2,
ignore MAS spaces: 2-1,
ignore MAS spaces: 2+0,
ignore MAS spaces: 2+1])
test(Equivalent whitespace characters.,
[Equiv. spaces: 3-3,
"Equiv. \rspaces: 3-2",
"Equiv. \x0cspaces: 3-1",
"Equiv. \x0bspaces: 3+0",
"Equiv. \nspaces: 3+1",
"Equiv. \tspaces: 3+2"])
test(Case Independent sort.,
[cASE INDEPENDENT: 3-2,
caSE INDEPENDENT: 3-1,
casE INDEPENDENT: 3+0,
case INDEPENDENT: 3+1])
test(Numeric fields as numerics.,
[foo100bar99baz0.txt,
foo100bar10baz0.txt,
foo1000bar99baz10.txt,
foo1000bar99baz9.txt])
test(Title sorts.,
[The Wind in the Willows,
The 40th step more,
The 39 steps,
Wanda])