package main
import (
"sort"
"sync"
)
type wordsByCount struct {
words *map[string]uint
keys []string
}
func newWordsByCount(w *map[string]uint) wordsByCount {
keys := make([]string, len(*w))
i := 0
for w, _ := range *w {
keys[i] = w
i++
}
return wordsByCount{words: w, keys: keys}
}
func (wbc wordsByCount) Len() int { return len(*wbc.words) }
func (wbc wordsByCount) Swap(i, j int) {
wbc.keys[i], wbc.keys[j] = wbc.keys[j], wbc.keys[i]
}
func (wbc wordsByCount) Less(i, j int) bool {
return (*wbc.words)[wbc.keys[i]] > (*wbc.words)[wbc.keys[j]]
}
func (wbc wordsByCount) MostCommonWords() []string {
sort.Sort(wbc)
mcw := make([]string, len(*wbc.words))
for i, p := range wbc.keys {
mcw[i] = p
}
return mcw
}
type Model struct {
lock sync.RWMutex
words map[string]uint
}
func NewModel() Model {
return Model{words: make(map[string]uint)}
}
func (m *Model) AddWords(words []string) {
m.lock.Lock()
defer m.lock.Unlock()
for _, word := range words {
v, _ := m.words[word]
m.words[word] = v + 1
}
}
func (m *Model) GetMostCommonPairs(how_many uint) []string {
m.lock.RLock()
defer m.lock.RUnlock()
wbc := newWordsByCount(&m.words)
mcw := wbc.MostCommonWords()
return mcw[:how_many]
}