words.go

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