Initial Commit
This commit is contained in:
commit
3f2bd39bcf
113
search.go
Normal file
113
search.go
Normal file
@ -0,0 +1,113 @@
|
||||
package search
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var ignoreWords = []string{`a`, `of`, `in`, `the`, `wa`, `ga`, `no`, `ni`, `wo`, `he`, `o`, `ka`}
|
||||
var replaceCharacters = strings.Split(`〜☆♪・〈〉「」!『』²Ⅱ+[](),.!?\/{}+-_=~"'@#$%^&*|;:<>`, ``)
|
||||
|
||||
// ID ...
|
||||
type ID struct {
|
||||
ID int
|
||||
Score float64
|
||||
Title []string
|
||||
}
|
||||
|
||||
// Search ...
|
||||
type Search struct {
|
||||
Titles map[interface{}][][]string
|
||||
IgnoreWords []string
|
||||
RemoveCharacters []string
|
||||
}
|
||||
|
||||
// CleanSearch ...
|
||||
func CleanSearch(title string) []string {
|
||||
s := []string{}
|
||||
for _, c := range replaceCharacters {
|
||||
title = strings.Replace(title, c, ` `, -1)
|
||||
}
|
||||
for _, v := range strings.Split(title, ` `) {
|
||||
matched := false
|
||||
if v == `` || v == ` ` {
|
||||
continue
|
||||
}
|
||||
for _, w := range ignoreWords {
|
||||
if v == w {
|
||||
matched = true
|
||||
}
|
||||
}
|
||||
if !matched {
|
||||
s = append(s, strings.ToLower(v))
|
||||
}
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// IndexSearch ...
|
||||
func (DB *Search) IndexSearch(id interface{}, st [][]string) {
|
||||
if DB.Titles == nil {
|
||||
DB.Titles = make(map[interface{}][][]string)
|
||||
}
|
||||
for _, t := range st {
|
||||
DB.Titles[id] = append(DB.Titles[id], t)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Match ...
|
||||
func (DB *Search) Match(Title string) []interface{} {
|
||||
IDS := []ID{}
|
||||
title := CleanSearch(strings.ToLower(Title))
|
||||
mainLoop:
|
||||
for i := range DB.Titles {
|
||||
for _, t := range DB.Titles[i] {
|
||||
if len(t) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
sim := similarity(t, title)
|
||||
if sim > 0 {
|
||||
IDS = append(IDS, ID{ID: i.(int), Score: sim, Title: t})
|
||||
continue mainLoop
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(IDS, func(i, j int) bool {
|
||||
return IDS[i].Score > IDS[j].Score
|
||||
})
|
||||
|
||||
ids := []interface{}{}
|
||||
for _, v := range IDS {
|
||||
ids = append(ids, v.ID)
|
||||
}
|
||||
return ids
|
||||
}
|
||||
|
||||
func similarity(a, b []string) float64 {
|
||||
var s float64
|
||||
var matched []int
|
||||
loop:
|
||||
for _, i := range a {
|
||||
for f, l := range b {
|
||||
if i == l && !intInSlice(f, matched) {
|
||||
s++
|
||||
matched = append(matched, f)
|
||||
continue loop
|
||||
} else {
|
||||
s = s - 0.125
|
||||
}
|
||||
}
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func intInSlice(a int, list []int) bool {
|
||||
for _, b := range list {
|
||||
if b == a {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
Loading…
Reference in New Issue
Block a user