Changed mention results sorting.
Smartcase has been disabled.
Characters which match case sensitivity are rewarded more points.
MODIFY
util/fuzzy/fuzzy.go
util/fuzzy/fuzzy.go
@@ -3,6 +3,7 @@ package fuzzy
import (
"sort"
"strings"
+ "unicode"
)
type SearchResult struct {
@@ -12,18 +13,9 @@ type SearchResult struct {
func ScoreSearch(searchTerm string, searchItems []string) map[string]float64 {
mymap := make(map[string]float64)
- // Ignore case if there are no capital letters in the search term.
- caseInsensitive := searchTerm == strings.ToLower(searchTerm)
- if caseInsensitive {
- searchTerm = strings.ToLower(searchTerm)
- }
for _, str := range searchItems {
- if caseInsensitive {
- mymap[str] = Score(searchTerm, strings.ToLower(str))
- } else {
mymap[str] = Score(searchTerm, str)
}
- }
return mymap
}
@@ -63,38 +55,35 @@ func Score(needle, haystack string) float64 {
return 0
}
+ lowerNeedle := strings.ToLower(needle)
+ lowerHaystack := strings.ToLower(haystack)
score := 0.0
- needleIndex := 0
- for haystackIndex := 0; needleIndex < needleLength; haystackIndex++ {
+ for i, j := 0, 0; i < needleLength; i, j = i+1, j+1 {
- letterIndex := findLetterIndex(needle[needleIndex], haystack, haystackIndex)
+ letter := lowerNeedle[i]
+ letterIndex := strings.IndexByte(lowerHaystack[j:], letter)
if letterIndex < 0 {
return -1
}
- if letterIndex == haystackIndex {
+ if areLettersSameCase(needle[i], haystack[j]) {
+ score += 0.5
+ }
+
+ if letterIndex == j {
// Letter was consecutive
score += 8
} else {
score += 1 - (0.1 * float64(letterIndex))
- // Move haystackIndex up to the next found letter.
- haystackIndex = letterIndex
+ // Move j up to the next found letter.
+ j = letterIndex
}
- needleIndex++
}
return score
}
-// Scores a letter from inside a string based on its distance from the start of the string.
-// The index at which the letter was found will be returned.
-// The score and index will be -1 if the character is not found.
-func findLetterIndex(c byte, haystack string, startIndex int) int {
- for i := startIndex; i < len(haystack); i++ {
- if c == haystack[i] {
- return i
- }
- }
- // Letter not found.
- return -1
+func areLettersSameCase(letterA, letterB byte) bool {
+ return unicode.IsUpper(rune(letterA)) && unicode.IsUpper(rune(letterB)) ||
+ unicode.IsLower(rune(letterA)) && unicode.IsLower(rune(letterB))
}

MODIFY
util/fuzzy/fuzzy_test.go
util/fuzzy/fuzzy_test.go
@@ -16,9 +16,9 @@ func TestFuzzyScore(t *testing.T) {
t.Errorf("Incorrect score rating")
}
- arr := []string{"tests", "test", "testosterone", "atesta", "bob"}
- sorted := SortSearchResults(ScoreSearch("te", arr))
- expected := [4]string{"test", "testosterone", "tests", "atesta"}
+ arr := []string{"tests", "test", "Testosterone", "atesta", "bob"}
+ sorted := SortSearchResults(ScoreSearch("Te", arr))
+ expected := [4]string{"Testosterone", "test", "tests", "atesta"}
if len(sorted) != len(expected) {
t.Errorf("Expected length of %d, but received %d.\n", len(expected), len(sorted))
@@ -37,16 +37,16 @@ func TestFuzzyScore(t *testing.T) {
t.Errorf("Expected score to be < 0\n")
}
- if Score("S", "scheme god#2313") >= 0 {
- t.Errorf("Expected score to be < 0\n")
+ if Score("S", "scheme god#2313") <= 0 {
+ t.Errorf("Expected score to be > 0\n")
}
if Score("K", "KC") <= 0 {
- t.Errorf("Expected score to be < 0\n")
+ t.Errorf("Expected score to be > 0\n")
}
if Score("s", "space") <= 0 {
- t.Errorf("Expected score to be < 0\n")
+ t.Errorf("Expected score to be > 0\n")
}
}

Changed mention results sorting.

-Smartcase has been disabled.
-Characters which match case sensitivity are rewarded more points.