package search import ( "fmt" "sort" "strings" ) // ID ... type ID struct { ID int Score float64 Title []string } // Search ... type Search struct { Titles map[interface{}][][]string IgnoreWords []string RemoveCharacters []string } // CleanSearch ... func (DB *Search) CleanSearch(title string) []string { s := []string{} for _, c := range DB.RemoveCharacters { title = strings.Replace(title, c, ` `, -1) } for _, v := range strings.Split(title, ` `) { matched := false if v == `` || v == ` ` { continue } for _, w := range DB.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) } } // Ignore ... func (DB *Search) Ignore(list []string) { DB.IgnoreWords = list } // Replace ... func (DB *Search) Replace(list []string) { DB.RemoveCharacters = list } // Match ... func (DB *Search) Match(Title string) []interface{} { IDS := []ID{} title := DB.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 } } } fmt.Println(DB.Titles[1]) fmt.Println(DB.Titles[`1`]) 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 }