create sortpath

This commit is contained in:
Celogeek 2023-04-08 18:31:30 +02:00
parent d9c817f27e
commit 01b0486966
Signed by: celogeek
SSH Key Fingerprint: SHA256:njNJLzoLQdbV9PC6ehcruRb0QnEgxABoCYZ+0+aUIYc

View File

@ -0,0 +1,83 @@
package sortpath
import (
"path/filepath"
"regexp"
"strconv"
"strings"
)
var split_path_regex = regexp.MustCompile(`^(.*?)(\d+)$`)
type part struct {
name string
number int
}
func (a part) Compare(b part) int {
if a.name == b.name {
return a.number - b.number
} else {
return strings.Compare(a.name, b.name)
}
}
func parsePart(p string) part {
r := split_path_regex.FindStringSubmatch(p)
if len(r) == 0 {
return part{p, 0}
}
n, err := strconv.ParseInt(r[2], 10, 32)
if err != nil {
return part{p, 0}
}
return part{r[1], int(n)}
}
func parse(filename string) []part {
pathname, name := filepath.Split(strings.ToLower(filename))
pathname = strings.TrimSuffix(pathname, string(filepath.Separator))
ext := filepath.Ext(name)
name = name[0 : len(name)-len(ext)]
f := []part{}
for _, p := range strings.Split(pathname, string(filepath.Separator)) {
f = append(f, parsePart(p))
}
f = append(f, parsePart(name))
return f
}
func comparePart(a, b []part) int {
m := len(a)
if m > len(b) {
m = len(b)
}
for i := 0; i < m; i++ {
c := a[i].Compare(b[i])
if c != 0 {
return c
}
}
return len(a) - len(b)
}
type by struct {
filenames []string
paths [][]part
}
func (b by) Len() int { return len(b.filenames) }
func (b by) Less(i, j int) bool { return comparePart(b.paths[i], b.paths[j]) < 0 }
func (b by) Swap(i, j int) {
b.filenames[i], b.filenames[j] = b.filenames[j], b.filenames[i]
b.paths[i], b.paths[j] = b.paths[j], b.paths[i]
}
func By(filenames []string) by {
p := [][]part{}
for _, filename := range filenames {
p = append(p, parse(filename))
}
return by{filenames, p}
}