diff --git a/CHANGELOG.md b/CHANGELOG.md index 4731e82d..46b06824 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,29 +1,33 @@ ## Changelog +### [13.13.1](https://kaos.sh/ek/13.13.1) + +- `[spellcheck]` Distance calculation method now public + ### [13.13.0](https://kaos.sh/ek/13.13.0) -* `[req]` Added support for different types of slices to `Query` -* `[req]` Added support for `fmt.Stringer` interface to `Query` -* `[req]` Added interface for custom struct encoding for `Query` -* `[req]` Improved `Query`encoding +- `[req]` Added support for different types of slices to `Query` +- `[req]` Added support for `fmt.Stringer` interface to `Query` +- `[req]` Added interface for custom struct encoding for `Query` +- `[req]` Improved `Query`encoding ### [13.12.0](https://kaos.sh/ek/13.12.0) -* `[req]` Added custom timeout per request -* `[req]` Added `Retrier` -* `[req]` Make `Limiter` public -* `[log]` Added `WithFullCallerPath` option to enable the output of the full caller path -* `[strutil]` Added support of escaped strings to `Fields` -* `[strutil]` Added fuzz tests for `Fields` method -* `[knf]` Fixed build of fuzz tests +- `[req]` Added custom timeout per request +- `[req]` Added `Retrier` +- `[req]` Make `Limiter` public +- `[log]` Added `WithFullCallerPath` option to enable the output of the full caller path +- `[strutil]` Added support of escaped strings to `Fields` +- `[strutil]` Added fuzz tests for `Fields` method +- `[knf]` Fixed build of fuzz tests ### [13.11.0](https://kaos.sh/ek/13.11.0) -* `[req]` Added request limiter +- `[req]` Added request limiter ### [13.10.1](https://kaos.sh/ek/13.10.1) -* `[mathutil]` Added shorthand helper `B` +- `[mathutil]` Added shorthand helper `B` ### [13.10.0](https://kaos.sh/ek/13.10.0) diff --git a/spellcheck/spellcheck.go b/spellcheck/spellcheck.go index 63a133c9..1d970c49 100644 --- a/spellcheck/spellcheck.go +++ b/spellcheck/spellcheck.go @@ -33,17 +33,9 @@ type suggestItem struct { type suggestItems []*suggestItem -func (s suggestItems) Len() int { - return len(s) -} - -func (s suggestItems) Less(i, j int) bool { - return s[i].score < s[j].score -} - -func (s suggestItems) Swap(i, j int) { - s[i], s[j] = s[j], s[i] -} +func (s suggestItems) Len() int { return len(s) } +func (s suggestItems) Less(i, j int) bool { return s[i].score < s[j].score } +func (s suggestItems) Swap(i, j int) { s[i], s[j] = s[j], s[i] } // ////////////////////////////////////////////////////////////////////////////////// // @@ -68,62 +60,8 @@ func Train(words []string) *Model { return model } -// ////////////////////////////////////////////////////////////////////////////////// // - -// Correct corrects given value -func (m *Model) Correct(word string) string { - if m == nil || len(m.terms) == 0 { - return word - } - - var result *suggestItem - - for _, si := range getSuggestSlice(m.terms, word) { - if result == nil { - result = si - continue - } - - if si.score < result.score { - result = si - continue - } - } - - if result.score > mathutil.Between(m.Threshold, 1, 1000) { - return word - } - - return result.term -} - -// Suggest suggests words for given word or word part -func (m *Model) Suggest(word string, max int) []string { - if m == nil || len(m.terms) == 0 { - return []string{word} - } - - if max == 1 { - return []string{m.Correct(word)} - } - - sis := getSuggestSlice(m.terms, word) - - sort.Sort(sis) - - var result []string - - for i := 0; i < mathutil.Between(max, 1, len(sis)); i++ { - result = append(result, sis[i].term) - } - - return result -} - -// ////////////////////////////////////////////////////////////////////////////////// // - -// Damerau–Levenshtein distance algorithm and code -func getDLDistance(source, target string) int { +// Distance calculates distance using Damerau–Levenshtein algorithm +func Distance(source, target string) int { sl, tl := len(source), len(target) if sl == 0 { @@ -184,11 +122,65 @@ func getDLDistance(source, target string) int { return h[sl+1][tl+1] } +// ////////////////////////////////////////////////////////////////////////////////// // + +// Correct corrects given value +func (m *Model) Correct(word string) string { + if m == nil || len(m.terms) == 0 { + return word + } + + var result *suggestItem + + for _, si := range getSuggestSlice(m.terms, word) { + if result == nil { + result = si + continue + } + + if si.score < result.score { + result = si + continue + } + } + + if result.score > mathutil.Between(m.Threshold, 1, 1000) { + return word + } + + return result.term +} + +// Suggest suggests words for given word or word part +func (m *Model) Suggest(word string, max int) []string { + if m == nil || len(m.terms) == 0 { + return []string{word} + } + + if max == 1 { + return []string{m.Correct(word)} + } + + sis := getSuggestSlice(m.terms, word) + + sort.Sort(sis) + + var result []string + + for i := 0; i < mathutil.Between(max, 1, len(sis)); i++ { + result = append(result, sis[i].term) + } + + return result +} + +// ////////////////////////////////////////////////////////////////////////////////// // + func getSuggestSlice(terms []string, word string) suggestItems { var result suggestItems for _, t := range terms { - result = append(result, &suggestItem{t, getDLDistance(strings.ToLower(t), strings.ToLower(word))}) + result = append(result, &suggestItem{t, Distance(strings.ToLower(t), strings.ToLower(word))}) } return result diff --git a/version.go b/version.go index 50dde6ee..242ee83f 100644 --- a/version.go +++ b/version.go @@ -8,4 +8,4 @@ package ek // ////////////////////////////////////////////////////////////////////////////////// // // VERSION is current ek package version -const VERSION = "13.13.0" +const VERSION = "13.13.1"