-
Notifications
You must be signed in to change notification settings - Fork 4
/
lexorank.go
62 lines (51 loc) · 1.11 KB
/
lexorank.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
// Package lexorank is a simple implementation of LexoRank.
//
// LexoRank is a ranking system introduced by Atlassian JIRA.
// For details - https://www.youtube.com/watch?v=OjQv9xMoFbg
package lexorank
const (
minChar = byte('0')
maxChar = byte('z')
)
// Rank returns a new rank string between prev and next.
// ok=false if it needs to be reshuffled. e.g. same or adjacent prev, next values.
func Rank(prev, next string) (string, bool) {
if prev == "" {
prev = string(minChar)
}
if next == "" {
next = string(maxChar)
}
rank := ""
i := 0
for {
prevChar := getChar(prev, i, minChar)
nextChar := getChar(next, i, maxChar)
if prevChar == nextChar {
rank += string(prevChar)
i++
continue
}
midChar := mid(prevChar, nextChar)
if midChar == prevChar || midChar == nextChar {
rank += string(prevChar)
i++
continue
}
rank += string(midChar)
break
}
if rank >= next {
return prev, false
}
return rank, true
}
func mid(prev, next byte) byte {
return (prev + next) / 2
}
func getChar(s string, i int, defaultChar byte) byte {
if i >= len(s) {
return defaultChar
}
return s[i]
}