Word Frequency Counter
Counts word frequency from a block of text, then sorts results by count. Demonstrates maps, the comma-ok pattern, and slice sorting.
package main
import (
"fmt"
"sort"
"strings"
)
type WordCount struct {
Word string
Count int
}
func countWords(text string) map[string]int {
freq := make(map[string]int)
// Normalize and split
text = strings.ToLower(text)
replacer := strings.NewReplacer(",", "", ".", "", "!", "", "?", "", "'", "")
text = replacer.Replace(text)
words := strings.Fields(text)
for _, word := range words {
freq[word]++
}
return freq
}
func topN(freq map[string]int, n int) []WordCount {
counts := make([]WordCount, 0, len(freq))
for word, count := range freq {
counts = append(counts, WordCount{Word: word, Count: count})
}
sort.Slice(counts, func(i, j int) bool {
if counts[i].Count == counts[j].Count {
return counts[i].Word < counts[j].Word
}
return counts[i].Count > counts[j].Count
})
if n > len(counts) {
n = len(counts)
}
return counts[:n]
}
func main() {
text := `Go is an open source programming language that makes it simple to
build reliable and efficient software. Go is expressive, concise,
clean, and efficient. Its concurrency mechanisms make it easy to write
programs that get the most out of multicore and networked machines,
while its novel type system enables flexible and modular program
construction. Go compiles quickly to machine code yet has the
convenience of garbage collection and the power of run time reflection.
It is a fast, statically typed, compiled language that feels like a
dynamically typed, interpreted language.`
freq := countWords(text)
fmt.Printf("Total unique words: %d\n\n", len(freq))
// Comma-ok pattern: check if specific words exist
targets := []string{"go", "rust", "concurrency", "python"}
fmt.Println("Word lookup:")
for _, word := range targets {
if count, ok := freq[word]; ok {
fmt.Printf(" %q: found %d times\n", word, count)
} else {
fmt.Printf(" %q: not found\n", word)
}
}
// Top 10 words
fmt.Println("\nTop 10 words:")
for i, wc := range topN(freq, 10) {
bar := strings.Repeat("█", wc.Count)
fmt.Printf(" %2d. %-12s %s (%d)\n", i+1, wc.Word, bar, wc.Count)
}
// Delete stop words and recount
stopWords := []string{"a", "an", "the", "and", "is", "it", "to", "of", "that", "its"}
for _, sw := range stopWords {
delete(freq, sw)
}
fmt.Println("\nTop 5 (after removing stop words):")
for i, wc := range topN(freq, 5) {
fmt.Printf(" %2d. %-12s (%d)\n", i+1, wc.Word, wc.Count)
}
}