Tạo tập hợp
Thuộc phần Logic và luồng điều khiển trong hành trình GO của Coddy. Bài học 32 trên 68.
Giờ bạn đã hiểu ý tưởng đằng sau cách dùng set trong Go, đã đến lúc thực hành bằng cách tạo tập hợp đầu tiên. Cách làm rất đơn giản và theo cùng quy tắc bạn đã học với map.
Để tạo một tập hợp trong Go, bạn khai báo một biến bằng mẫu map[T]struct{}, trong đó T là kiểu dữ liệu của các phần tử bạn muốn lưu trữ. Sau đây là cách tạo một tập hợp để lưu trữ các tên màu duy nhất:
colors := make(map[string]struct{})Bạn cũng có thể khởi tạo một tập hợp với một số giá trị ban đầu bằng cú pháp map literal:
colors := map[string]struct{}{
"red": {},
"blue": {},
"green": {},
}Lưu ý rằng mỗi giá trị đều là một giá trị cấu trúc rỗng {}. Giá trị này tạo ra giá trị không của struct{}, không chiếm bộ nhớ nhưng vẫn cho phép khóa tồn tại trong map.
Điểm hay của cách tiếp cận này là tận dụng cơ sở hạ tầng map sẵn có của Go, đồng thời mang lại ngữ nghĩa tập hợp thực sự: mỗi tên màu chỉ có thể xuất hiện một lần và bạn có thể tra cứu nhanh như với các map thông thường.
Thử thách
DễTạo một công cụ theo dõi ngôn ngữ lập trình yêu thích, minh họa cách dùng quy ước tập hợp (set) của Go để lưu các phần tử duy nhất. Thử thách này cho bạn thấy cách dùng mẫu map[string]struct{} để theo dõi các ngôn ngữ lập trình mà không bị trùng lặp.
Bạn sẽ nhận được hai đầu vào:
- Một chuỗi biểu thị số ngôn ngữ cần xử lý (ví dụ:
"6") - Một chuỗi chứa các ngôn ngữ lập trình, phân tách bằng dấu phẩy (ví dụ:
"Go,Python,JavaScript,Go,Java,Python,C++,JavaScript")
Nhiệm vụ của bạn là:
- Tạo một tập hợp bằng quy ước của Go
map[string]struct{}để lưu các ngôn ngữ lập trình duy nhất - Phân tích chuỗi đầu vào bằng cách tách chuỗi tại các dấu phẩy để lấy tên từng ngôn ngữ
- Thêm từng ngôn ngữ vào tập hợp bằng cách dùng giá trị cấu trúc rỗng
{} - Hiển thị kết quả xử lý bằng cách in ra từng ngôn ngữ khi gặp ngôn ngữ đó:
- Nếu ngôn ngữ chưa có trong tập hợp:
"Added: [language]" - Nếu ngôn ngữ đã có trong tập hợp:
"Already exists: [language]"
- Nếu ngôn ngữ chưa có trong tập hợp:
- Sau khi xử lý tất cả ngôn ngữ, hiển thị phần tổng kết:
"Total languages processed: [total_count]""Unique languages: [unique_count]"
- Cuối cùng, liệt kê tất cả ngôn ngữ duy nhất trong tập hợp:
- Tiêu đề:
"Programming languages in set:" - Mỗi ngôn ngữ trên một dòng riêng:
"- [language]"
- Tiêu đề:
Dùng gói strings để tách chuỗi đầu vào và gói strconv để chuyển chuỗi số lượng thành số nguyên. Để kiểm tra xem một ngôn ngữ đã có trong tập hợp hay chưa trước khi thêm, hãy dùng quy ước dấu phẩy ok: _, exists := languageSet[language]. Thử thách này cho thấy quy ước tập hợp của Go giúp theo dõi các phần tử duy nhất và ngăn dữ liệu bị trùng lặp một cách hiệu quả.
Tự làm thử
package main
import (
"fmt"
"sort"
"strconv"
"strings"
)
func main() {
// Đọc đầu vào
var countStr string
var languagesStr string
fmt.Scanln(&countStr)
fmt.Scanln(&languagesStr)
// Chuyển chuỗi count thành số nguyên (không cần cho thử thách này)
_, _ = strconv.Atoi(countStr)
// Tách chuỗi languages theo dấu phẩy
languages := strings.Split(languagesStr, ",")
// Tạo tập hợp bằng cách dùng mẫu map[string]struct{}
languageSet := make(map[string]struct{})
// TODO: Viết code bên dưới
// Xử lý từng ngôn ngữ và kiểm tra xem nó có trong tập hợp không
// Dùng mẫu comma ok: _, exists := languageSet[language]
// In ra "Added: [language]" hoặc "Already exists: [language]"
// Thêm các ngôn ngữ vào tập hợp bằng giá trị struct rỗng {}
// In ra thông tin tóm tắt
// In ra tổng số ngôn ngữ đã xử lý và số ngôn ngữ không trùng lặp
// In ra tất cả ngôn ngữ không trùng lặp trong tập hợp
fmt.Println("Programming languages in set:")
// Chuyển map thành slice rồi sắp xếp để đầu ra luôn theo cùng một thứ tự
// Liệt kê từng ngôn ngữ theo định dạng "- [language]"
}Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Logic và luồng điều khiển
1Luồng điều khiển nâng cao
Switch với `fallthrough`Thoát khỏi vòng lặp lồng nhauTiếp tục một vòng lặp cụ thểCâu lệnh `goto`Ôn tập: điều khiển vòng lặp nâng cao4Dự án: Danh sách việc cần làm đơn giản
Thiết lập dự ánThêm một việc cần làm2Struct và phương thức
Định nghĩa phương thức cho structReceiver giá trịReceiver con trỏChọn receiverPhương thức và hàmÔn tập: hành vi của struct5Tìm hiểu chuyên sâu về map
Map chứa structCon trỏ làm giá trị của mapKiểm tra map nilSo sánh các mapÔn tập: bộ đếm tần suất từ8Dự án: Quản lý hàng tồn kho đơn giản
Tổng quan dự ánKiểm tra hàng tồn kho3Interface (cơ bản)
Interface là gì?Định nghĩa interfaceTriển khai interfaceDùng kiểu interfaceInterface rỗngKhẳng định kiểuType switchÔn tập: hình dạng và hành vi6Go theo cách viết thành ngữ: tập hợp
Cách dùng tập hợp trong GoTạo tập hợpThêm phần tử vào tập hợpKiểm tra phần tử có thuộc tập hợp khôngXóa phần tử khỏi tập hợpLặp qua tập hợpÔn tập: tên người dùng duy nhấtTự luyện tập: Trình biên dịch Go online