Map

Map là gì?

Map là cấu trúc dữ liệu key-value, tương tự dictionary (Python), HashMap (Java). Lookup O(1).

// Khai báo với literal
m := map[string]int{
    "An":   20,
    "Bình": 25,
    "Chi":  22,
}

// Khai báo rỗng với make
m2 := make(map[string]int)

// CẢNH BÁO: map nil không dùng được để ghi
var m3 map[string]int  // nil map
m3["key"] = 1          // PANIC: assignment to entry in nil map

Thêm, đọc, cập nhật

m := make(map[string]int)

// Thêm / cập nhật (cùng cú pháp)
m["Go"] = 2009
m["Python"] = 1991
m["Go"] = 2009  // ghi đè

// Đọc
year := m["Go"]  // 2009

// Đọc key không tồn tại: trả về zero value, KHÔNG panic
year2 := m["Rust"]  // 0 (zero value của int)

Comma-ok idiom — Kiểm tra key tồn tại

// Cách đúng để kiểm tra key
year, ok := m["Rust"]
if ok {
    fmt.Println("Rust ra mắt năm:", year)
} else {
    fmt.Println("Không có Rust trong map")
}

// Viết gọn
if year, ok := m["Java"]; ok {
    fmt.Println(year)
}

Xóa phần tử

delete(m, "Python")
// delete không panic nếu key không tồn tại — an toàn

Duyệt map — thứ tự NGẪU NHIÊN

for key, value := range m {
    fmt.Printf("%s: %d\n", key, value)
}
// Thứ tự in ra khác nhau mỗi lần chạy!

// Để in theo thứ tự: lấy keys ra, sort, rồi in
keys := make([]string, 0, len(m))
for k := range m {
    keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
    fmt.Printf("%s: %d\n", k, m[k])
}

Set — Tập hợp không trùng lặp

// Dùng map[T]struct{} vì struct{} không tốn memory
set := make(map[string]struct{})
set["go"] = struct{}{}
set["python"] = struct{}{}
set["go"] = struct{}{}  // trùng, không có hiệu lực

_, exists := set["go"]  // true

Map lồng nhau

// Map of slices
groups := map[string][]string{
    "backend":  {"Go", "Python", "Java"},
    "frontend": {"TypeScript", "React"},
}
groups["backend"] = append(groups["backend"], "Rust")

// Map of maps
config := map[string]map[string]string{
    "db":    {"host": "localhost", "port": "5432"},
    "redis": {"host": "localhost", "port": "6379"},
}
example.go
package main

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

func demTuNgu(vanBan string) map[string]int {
	tu := strings.Fields(strings.ToLower(vanBan))
	dem := make(map[string]int)
	for _, t := range tu {
		dem[t]++
	}
	return dem
}

func main() {
	text := "go là ngôn ngữ go tuyệt vời go rất nhanh python cũng tốt"
	dem := demTuNgu(text)

	// In theo thứ tự alphabet
	keys := make([]string, 0, len(dem))
	for k := range dem {
		keys = append(keys, k)
	}
	sort.Strings(keys)

	fmt.Println("Tần suất từ:")
	for _, k := range keys {
		fmt.Printf("  %-10s: %d\n", k, dem[k])
	}

	// Nhóm số theo chẵn/lẻ
	nums := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
	nhom := make(map[string][]int)
	for _, n := range nums {
		if n%2 == 0 {
			nhom["chẵn"] = append(nhom["chẵn"], n)
		} else {
			nhom["lẻ"] = append(nhom["lẻ"], n)
		}
	}
	fmt.Println("\nSố chẵn:", nhom["chẵn"])
	fmt.Println("Số lẻ:  ", nhom["lẻ"])
}