Map lồng nhau
Thuộc phần Logic và luồng điều khiển trong hành trình Dart của Coddy. Bài học 31 trên 65.
Đôi khi, bạn cần sắp xếp dữ liệu theo cấu trúc phân cấp phức tạp hơn một cặp khóa-giá trị đơn giản. Bản đồ lồng nhau cho phép bạn lưu các bản đồ làm giá trị bên trong những bản đồ khác, tạo ra nhiều cấp độ sắp xếp dữ liệu.
Bản đồ lồng nhau (nested map) đơn giản là một Map mà các giá trị cũng là những đối tượng Map. Cấu trúc này rất phù hợp để biểu diễn dữ liệu có danh mục và danh mục con, chẳng hạn như hồ sơ người dùng với nhiều thông tin chi tiết hoặc danh mục sản phẩm với nhiều thuộc tính.
Map<String, Map<String, dynamic>> userProfiles = {
'alice': {
'email': 'alice@example.com',
'age': 28
},
'bob': {
'email': 'bob@example.com',
'age': 32
}
};
print(userProfiles['alice']['email']); // alice@example.com
print(userProfiles['bob']['age']); // 32Để truy cập dữ liệu trong một map lồng nhau, bạn dùng nhiều cặp dấu ngoặc vuông. Cặp đầu tiên truy cập khóa của map bên ngoài, còn cặp thứ hai truy cập khóa của map bên trong. Cấu trúc hai cấp này giúp bạn dễ dàng nhóm các thông tin liên quan với nhau, đồng thời giữ cho chúng có tổ chức và dễ truy cập.
Thử thách
DễTạo một chương trình quản lý danh bạ nhân viên của công ty bằng các từ điển lồng nhau để lưu thông tin chi tiết về nhân viên. Chương trình của bạn cần:
- Đọc một chuỗi đầu vào biểu thị tên công ty
- Đọc nhiều nhóm dữ liệu đầu vào biểu thị thông tin nhân viên, quá trình đọc kết thúc khi bạn nhận được
"employees_done". Mỗi nhân viên có:- Mã nhân viên (chuỗi)
- Tên (chuỗi)
- Phòng ban (chuỗi)
- Lương (chuỗi cần chuyển đổi thành số nguyên)
- Số năm kinh nghiệm (chuỗi cần chuyển đổi thành số nguyên)
- Đọc một chuỗi đầu vào biểu thị mã nhân viên cần tra cứu
- Tạo một Map lồng nhau, trong đó mã nhân viên là khóa và giá trị là một Map khác chứa thông tin của nhân viên đó
- Truy cập và hiển thị thông tin cụ thể của nhân viên bằng cách truy cập từ điển lồng nhau
- Tính thống kê theo phòng ban và in báo cáo danh bạ nhân viên theo đúng định dạng bên dưới
Ví dụ, nếu tên công ty là "TechCorp Solutions", dữ liệu nhân viên gồm "EMP001" có tên "Alice Johnson", phòng ban "Engineering", lương 75000, kinh nghiệm 5; "EMP002" có tên "Bob Smith", phòng ban "Marketing", lương 60000, kinh nghiệm 3; "EMP003" có tên "Carol Davis", phòng ban "Engineering", lương 80000, kinh nghiệm 7, và mã nhân viên cần tra cứu là "EMP001", chương trình của bạn cần xuất:
Company: TechCorp Solutions
Employee Directory: {EMP001: {name: Alice Johnson, department: Engineering, salary: 75000, experience: 5}, EMP002: {name: Bob Smith, department: Marketing, salary: 60000, experience: 3}, EMP003: {name: Carol Davis, department: Engineering, salary: 80000, experience: 7}}
Employee Lookup (EMP001):
Name: Alice Johnson
Department: Engineering
Salary: $75000
Experience: 5 years
Department Analysis:
Engineering employees: 2
Marketing employees: 1
Total employees: 3
Average salary: $71666
Status: Employee directory processed successfullyNếu tên công ty là "Global Industries", dữ liệu nhân viên gồm "E100" có tên "David Wilson", phòng ban "Sales", lương 55000, kinh nghiệm 4; "E101" có tên "Emma Brown", phòng ban "HR", lương 65000, kinh nghiệm 6, và mã nhân viên cần tra cứu là "E101", chương trình của bạn cần xuất:
Company: Global Industries
Employee Directory: {E100: {name: David Wilson, department: Sales, salary: 55000, experience: 4}, E101: {name: Emma Brown, department: HR, salary: 65000, experience: 6}}
Employee Lookup (E101):
Name: Emma Brown
Department: HR
Salary: $65000
Experience: 6 years
Department Analysis:
Sales employees: 1
HR employees: 1
Total employees: 2
Average salary: $60000
Status: Employee directory processed successfullyNếu tên công ty là "StartupHub", dữ liệu nhân viên gồm "S001" có tên "Frank Miller", phòng ban "Development", lương 70000, kinh nghiệm 2; "S002" có tên "Grace Lee", phòng ban "Design", lương 58000, kinh nghiệm 3; "S003" có tên "Henry Chen", phòng ban "Development", lương 72000, kinh nghiệm 4; "S004" có tên "Ivy Taylor", phòng ban "Marketing", lương 62000, kinh nghiệm 5, và mã nhân viên cần tra cứu là "S003", chương trình của bạn cần xuất:
Company: StartupHub
Employee Directory: {S001: {name: Frank Miller, department: Development, salary: 70000, experience: 2}, S002: {name: Grace Lee, department: Design, salary: 58000, experience: 3}, S003: {name: Henry Chen, department: Development, salary: 72000, experience: 4}, S004: {name: Ivy Taylor, department: Marketing, salary: 62000, experience: 5}}
Employee Lookup (S003):
Name: Henry Chen
Department: Development
Salary: $72000
Experience: 4 years
Department Analysis:
Development employees: 2
Design employees: 1
Marketing employees: 1
Total employees: 4
Average salary: $65500
Status: Employee directory processed successfullyChương trình của bạn cần tạo cấu trúc Map lồng nhau, trong đó Map bên ngoài dùng mã nhân viên làm khóa, còn mỗi giá trị là một Map bên trong chứa các khóa "name", "department", "salary" và "experience". Dùng cách truy cập Map lồng nhau với hai cặp dấu ngoặc vuông để lấy thông tin cụ thể của nhân viên. Đếm số nhân viên theo phòng ban và tính lương trung bình bằng cách chia tổng lương cho số nhân viên. Định dạng đầu vào sẽ là: tên công ty, sau đó là các nhóm gồm năm giá trị (mã nhân viên, tên, phòng ban, lương, kinh nghiệm), kết thúc bằng "employees_done", rồi đến mã nhân viên cần tra cứu.
Tự làm thử
import 'dart:io';
void main() {
// Đọc tên công ty
String? companyName = stdin.readLineSync();
// Khởi tạo map lồng nhau cho danh bạ nhân viên
Map<String, Map<String, dynamic>> employeeDirectory = {};
// Đọc dữ liệu nhân viên cho đến khi gặp "employees_done"
while (true) {
String? input = stdin.readLineSync();
if (input == "employees_done") {
break;
}
String employeeId = input!;
String? name = stdin.readLineSync();
String? department = stdin.readLineSync();
String? salaryStr = stdin.readLineSync();
String? experienceStr = stdin.readLineSync();
// Chuyển lương và số năm kinh nghiệm thành số nguyên
int salary = int.parse(salaryStr!);
int experience = int.parse(experienceStr!);
// TODO: Tạo cấu trúc map lồng nhau cho từng nhân viên và thêm vào danh bạ
}
// Đọc ID nhân viên cần tra cứu
String? lookupId = stdin.readLineSync();
// TODO: Viết code bên dưới để:
// 1. Hiển thị tên công ty và danh bạ nhân viên
// 2. Tra cứu và hiển thị thông tin của một nhân viên cụ thể
// 3. Tính số liệu thống kê theo phòng ban
// 4. Tính lương trung bình
// 5. In ra báo cáo đầy đủ theo định dạng yêu cầu
}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
1Thao tác nâng cao với danh sách
Thuộc tính danh sách: đầu và cuốiTrạng thái danh sách: isEmpty và isNotEmpĐảo ngược danh sáchThêm vào danh sách: insertXóa khỏi danh sách: removeWhereTìm trong danh sách: indexOfSắp xếp danh sáchXáo trộn danh sáchÔn tập: trình sắp xếp danh sách4Thao tác nâng cao với Map
Duyệt qua MapKiểm tra khóa và giá trịCác thuộc tính của Map: khóa và giá trịThêm có điều kiện: putIfAbsentXóa mục khỏi MapMap lồng nhauÔn tập: Cập nhật kho hàng2Thao tác hàm trên danh sách
Biến đổi bằng 'map'Lọc bằng 'where'Dùng '.toList()'Kiểm tra điều kiện bằng 'any'Điều kiện với 'every'Tìm phần tử bằng 'firstWhere'Ôn tập: lọc dữ liệu5Dự án: Tính tiền giỏ hàng
Thiết lập dự ánThêm mặt hàng vào giỏ8Dự án: Trình phân tích văn bản đơn giản
Tổng quan và thiết lập dự ánĐếm ký tự3Tập hợp
Tập hợp là gì?Tạo tập hợpThêm và xóa phần tử khỏi tập hợpKiểm tra phần tử trong tập hợpChuyển danh sách thành tập hợpPhép hợp của các tập hợpPhép giao của các tập hợpPhép hiệu của các tập hợpÔn tập: danh sách khách mời không trùng lặpTự luyện tập: Trình biên dịch Dart online