// Week 4 – String basics in Go
// Run: go run ./w04/stringbasics
package main

import (
	"fmt"
	"sort"
	"strconv"
	"strings"
)

func main() {
	s := "Hello, World"

	// Length in BYTES, indexing gives a byte – O(1)
	fmt.Println("len =", len(s), ", s[4] =", s[4], "=", string(s[4]))

	// A string is immutable: s[0] = 'h' would be a compile error
	upper := strings.ToUpper(s)
	fmt.Println("s =", s, ", upper =", upper)

	// Comparison: in Go, == compares the CONTENTS
	a := "data"
	b := strings.Repeat("da", 1) + "ta"
	fmt.Println("a == b:", a == b)

	// Lexicographic comparison: with <, > or strings.Compare
	fmt.Println(`"apple" < "banana":`, "apple" < "banana", `, "Zebra" < "apple":`, "Zebra" < "apple")
	fmt.Println("EqualFold:", strings.EqualFold("Go", "GO"))

	// Searching
	fmt.Println("Index(o) =", strings.Index(s, "o"), ", LastIndex(o) =", strings.LastIndex(s, "o"),
		", Contains(World) =", strings.Contains(s, "World"))

	// Substring by slicing: [start:end) – BYTE indexes!
	fmt.Println("s[7:] =", s[7:], ", s[:5] =", s[:5])

	// Splitting, joining
	parts := strings.Split("Wuhan,Beijing,Shanghai", ",")
	fmt.Printf("Split: %q\n", parts)
	fmt.Println("Join: ", strings.Join(parts, " | "))
	fmt.Println("Fields:", strings.Fields("  between   several  spaces "))

	// Replacing, trimming
	fmt.Println("ReplaceAll:", strings.ReplaceAll(s, "World", "Hubei"))
	fmt.Printf("TrimSpace: [%s]\n", strings.TrimSpace("   text   "))

	// String <-> byte/rune slice
	r := []rune(s)
	sort.Slice(r, func(i, j int) bool { return r[i] < r[j] })
	fmt.Println("sorted characters:", strings.TrimSpace(string(r)))

	// Number <-> string
	n, err := strconv.Atoi("42")
	fmt.Println("Atoi + 1 =", n+1, err, ", Itoa =", strconv.Itoa(7)+"!")
}
