返回 DeepSeek-Reasonix
natsort.go
根目录 / internal / fileref / natsort.go
1 package fileref
2
3 import (
4 "strconv"
5 "strings"
6 "unicode"
7 )
8
9 // NaturalLess orders names the way file managers do: digit runs compare by
10 // numeric value ("file2" < "file10", "第2卷" < "第10卷"), everything else
11 // case-insensitively, and a digit sorts before a non-digit.
12 func NaturalLess(a, b string) bool {
13 a = strings.ToLower(a)
14 b = strings.ToLower(b)
15 ra := []rune(a)
16 rb := []rune(b)
17
18 i, j := 0, 0
19 for i < len(ra) && j < len(rb) {
20 aDig := unicode.IsDigit(ra[i])
21 bDig := unicode.IsDigit(rb[j])
22
23 if aDig && bDig {
24 aStart := i
25 for i < len(ra) && unicode.IsDigit(ra[i]) {
26 i++
27 }
28 bStart := j
29 for j < len(rb) && unicode.IsDigit(rb[j]) {
30 j++
31 }
32
33 aNum, _ := strconv.Atoi(string(ra[aStart:i]))
34 bNum, _ := strconv.Atoi(string(rb[bStart:j]))
35 if aNum != bNum {
36 return aNum < bNum
37 }
38 // Same numeric value: shorter digit string first (e.g. "1" < "01").
39 aLen := i - aStart
40 bLen := j - bStart
41 if aLen != bLen {
42 return aLen < bLen
43 }
44 } else if !aDig && !bDig {
45 if ra[i] != rb[j] {
46 return ra[i] < rb[j]
47 }
48 i++
49 j++
50 } else {
51 return aDig
52 }
53 }
54 return len(ra) < len(rb)
55 }
56
56 lines GO