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] }