Video Coming Soon...
40: sort, and uniq
This exercise is pending. Quick notes about this exercise:
- My implemention is at https://lcthw.dev/go/go-coreutils
- https://www.gnu.org/software/coreutils/manual/html_node/sort-invocation.html
- https://www.gnu.org/software/coreutils/manual/html_node/uniq-invocation.html
- slices -- https://pkg.go.dev/slices@go1.25.3
- strings -- https://pkg.go.dev/strings@go1.25.3
- maps -- https://pkg.go.dev/maps@go1.25.3
The sort Code
View Source file go-coreutils/sort/main.go Only
package main
import (
"fmt"
"bufio"
"os"
"slices"
"flag"
"strings"
"strconv"
)
type Opts struct {
IgnoreCase bool
Numeric bool
}
func parse_opts() Opts {
var opts Opts
flag.BoolVar(&opts.IgnoreCase, "f", false, "ignore case")
flag.BoolVar(&opts.Numeric, "n", false, "numeric sort")
flag.Parse()
return opts
}
func numeric_sort(a string, b string) int {
a_int, a_err := strconv.Atoi(a)
b_int, b_err := strconv.Atoi(b)
if a_err != nil || b_err != nil {
return strings.Compare(a, b)
} else {
return a_int - b_int
}
}
func ignore_case_sort(a string, b string) int {
return strings.Compare(strings.ToLower(a), strings.ToLower(b))
}
func main() {
lines := make([]string, 0, 100)
opts := parse_opts()
scan := bufio.NewScanner(os.Stdin)
for scan.Scan() {
line := scan.Text()
lines = append(lines, line)
}
if opts.Numeric {
slices.SortFunc(lines, numeric_sort)
} else if opts.IgnoreCase{
slices.SortFunc(lines, ignore_case_sort)
} else {
slices.Sort(lines)
}
for _, line := range lines {
fmt.Println(line)
}
}
The uniq Code
View Source file go-coreutils/uniq/main.go Only
package main
import (
"fmt"
"os"
"bufio"
"strings"
"flag"
)
type Opts struct {
IgnoreCase bool
Count bool
}
func parse_opts() Opts {
var opts Opts
flag.BoolVar(&opts.IgnoreCase, "i", false, "ignore case")
flag.BoolVar(&opts.Count, "c", false, "count occurence")
flag.Parse()
return opts
}
func string_equal(a string, b string, ignore_case bool) bool {
if ignore_case {
a = strings.ToLower(a)
b = strings.ToLower(b)
}
return strings.Compare(a, b) == 0
}
func main() {
scan := bufio.NewScanner(os.Stdin)
seen_line := ""
seen_count := 0
opts := parse_opts()
for scan.Scan() {
line := scan.Text()
if !string_equal(line, seen_line, opts.IgnoreCase) {
if opts.Count {
fmt.Print(seen_count, " ")
}
fmt.Println(line)
seen_line = line
seen_count = 0
} else {
seen_count++
}
}
}
Register for Learn Go the Hard Way
Register today for the course and get the all currently available videos and lessons, plus all future modules for no extra charge.