words.go

 1package words
 2
 3import (
 4	"bufio"
 5	"io"
 6	"strings"
 7)
 8
 9type List struct {
10	words [][]string
11	len   int
12}
13
14func newList(words []string) List {
15	return List{
16		words: [][]string{words},
17		len:   len(words),
18	}
19}
20
21func NewList(words []string) List {
22	cleaned := make([]string, 0, len(words))
23	for _, w := range words {
24		w = strings.TrimSpace(w)
25		w = strings.ToUpper(w)
26		cleaned = append(cleaned, w)
27	}
28	return newList(cleaned)
29}
30
31func NewListFromLines(r io.Reader) List {
32	var words []string
33	scanner := bufio.NewScanner(r)
34
35	for scanner.Scan() {
36		word := scanner.Text()
37		word = strings.TrimSpace(word)
38		word = strings.ToUpper(word)
39		if word != "" {
40			words = append(words, word)
41		}
42	}
43
44	return newList(words)
45}
46
47func (l *List) Len() int {
48	return l.len
49}
50
51func (l *List) Get(i int) string {
52	for _, words := range l.words {
53		if i < len(words) {
54			return words[i]
55		}
56		i -= len(words)
57	}
58	panic("out of bounds")
59}
60
61func (l List) Concat(other List) List {
62	words := make([][]string, 0, len(l.words)+len(other.words))
63	words = append(words, l.words...)
64	words = append(words, other.words...)
65
66	return List{
67		words: words,
68		len:   l.len + other.len,
69	}
70}