-
Notifications
You must be signed in to change notification settings - Fork 44
/
utils.go
73 lines (62 loc) · 2.06 KB
/
utils.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package govatar
import (
"math/rand"
"regexp"
"strings"
)
// randInt returns random integer
func randInt(rnd *rand.Rand, min int, max int) int {
return min + rnd.Intn(max-min)
}
// randStringSliceItem returns random element from slice of string
func randStringSliceItem(rnd *rand.Rand, slice []string) string {
return slice[randInt(rnd, 0, len(slice))]
}
type naturalSort []string
var r = regexp.MustCompile(`[^0-9]+|[0-9]+`)
func (s naturalSort) Len() int {
return len(s)
}
func (s naturalSort) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
func (s naturalSort) Less(i, j int) bool {
spliti := r.FindAllString(strings.Replace(s[i], " ", "", -1), -1)
splitj := r.FindAllString(strings.Replace(s[j], " ", "", -1), -1)
for index := 0; index < len(spliti) && index < len(splitj); index++ {
if spliti[index] != splitj[index] {
// Both slices are numbers
if isNumber(spliti[index][0]) && isNumber(splitj[index][0]) {
// Remove Leading Zeroes
stringi := strings.TrimLeft(spliti[index], "0")
stringj := strings.TrimLeft(splitj[index], "0")
if len(stringi) == len(stringj) {
for indexchar := 0; indexchar < len(stringi); indexchar++ {
if stringi[indexchar] != stringj[indexchar] {
return stringi[indexchar] < stringj[indexchar]
}
}
return len(spliti[index]) < len(splitj[index])
}
return len(stringi) < len(stringj)
}
// One of the slices is a number (we give precedence to numbers regardless of ASCII table position)
if isNumber(spliti[index][0]) || isNumber(splitj[index][0]) {
return isNumber(spliti[index][0])
}
// Both slices are not numbers
return spliti[index] < splitj[index]
}
}
// Fall back for cases where space characters have been annihilated by the replacement call
// Here we iterate over the unmolested string and prioritize numbers
for index := 0; index < len(s[i]) && index < len(s[j]); index++ {
if isNumber(s[i][index]) || isNumber(s[j][index]) {
return isNumber(s[i][index])
}
}
return s[i] < s[j]
}
func isNumber(input uint8) bool {
return input >= '0' && input <= '9'
}