ライブラリを番組一覧・番組ページ・再生の3段にする(ステップ12)
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
package web
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"gitea.kazu634.com/kazu634/tver/internal/store"
|
||||
)
|
||||
|
||||
func sortJobsNaturally(jobs []store.Job) {
|
||||
sort.SliceStable(jobs, func(i, j int) bool {
|
||||
if comparison := compareNaturalTitle(jobs[i].Title, jobs[j].Title); comparison != 0 {
|
||||
return comparison < 0
|
||||
}
|
||||
left, right := jobs[i].FinishedAt, jobs[j].FinishedAt
|
||||
if left == nil || right == nil {
|
||||
if left != right {
|
||||
return left == nil
|
||||
}
|
||||
} else if !left.Equal(*right) {
|
||||
return left.Before(*right)
|
||||
}
|
||||
return jobs[i].ID < jobs[j].ID
|
||||
})
|
||||
}
|
||||
|
||||
func compareNaturalTitle(left, right string) int {
|
||||
a, b := []rune(left), []rune(right)
|
||||
ai, bi := 0, 0
|
||||
for ai < len(a) && bi < len(b) {
|
||||
_, aIsDigit := decimalDigit(a[ai])
|
||||
_, bIsDigit := decimalDigit(b[bi])
|
||||
if aIsDigit && bIsDigit {
|
||||
var an, bn strings.Builder
|
||||
for ai < len(a) {
|
||||
digit, ok := decimalDigit(a[ai])
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
an.WriteByte(byte('0' + digit))
|
||||
ai++
|
||||
}
|
||||
for bi < len(b) {
|
||||
digit, ok := decimalDigit(b[bi])
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
bn.WriteByte(byte('0' + digit))
|
||||
bi++
|
||||
}
|
||||
if comparison := compareDecimal(an.String(), bn.String()); comparison != 0 {
|
||||
return comparison
|
||||
}
|
||||
continue
|
||||
}
|
||||
if a[ai] < b[bi] {
|
||||
return -1
|
||||
}
|
||||
if a[ai] > b[bi] {
|
||||
return 1
|
||||
}
|
||||
ai++
|
||||
bi++
|
||||
}
|
||||
if ai == len(a) && bi < len(b) {
|
||||
return -1
|
||||
}
|
||||
if bi == len(b) && ai < len(a) {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func decimalDigit(r rune) (int, bool) {
|
||||
switch {
|
||||
case '0' <= r && r <= '9':
|
||||
return int(r - '0'), true
|
||||
case '0' <= r && r <= '9':
|
||||
return int(r - '0'), true
|
||||
default:
|
||||
return 0, false
|
||||
}
|
||||
}
|
||||
|
||||
func compareDecimal(left, right string) int {
|
||||
left = strings.TrimLeft(left, "0")
|
||||
right = strings.TrimLeft(right, "0")
|
||||
if left == "" {
|
||||
left = "0"
|
||||
}
|
||||
if right == "" {
|
||||
right = "0"
|
||||
}
|
||||
if len(left) < len(right) {
|
||||
return -1
|
||||
}
|
||||
if len(left) > len(right) {
|
||||
return 1
|
||||
}
|
||||
return strings.Compare(left, right)
|
||||
}
|
||||
Reference in New Issue
Block a user