Вложенные Map
Часть раздела Логика и управление потоком путешествия по Dart на Coddy. Урок 31 из 65.
Иногда данные нужно организовать в более сложной иерархической структуре, чем простая пара «ключ — значение». Вложенные карты позволяют хранить карты в качестве значений внутри других карт, создавая несколько уровней организации данных.
Вложенная карта — это просто Map, значения в которой сами являются объектами Map. Такая структура идеально подходит для представления данных с категориями и подкатегориями, например профилей пользователей с несколькими подробностями или каталогов товаров с различными атрибутами.
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Чтобы получить доступ к данным во вложенной карте, используются несколько пар квадратных скобок. Первая пара обращается к ключу внешней карты, а вторая — к ключу внутренней карты. При поиске в карте возвращается null, если ключ отсутствует, поэтому в Dart после первого поиска нужен !, если вы знаете, что ключ существует: userProfiles['alice']!['email']. Такая двухуровневая структура позволяет легко группировать связанную информацию, сохраняя её упорядоченной и доступной.
Задание
ЛегкоСоздайте программу для управления системой справочника сотрудников компании, используя вложенные карты для хранения подробной информации о сотрудниках. Ваша программа должна:
- Считать строку, представляющую название компании
- Считать несколько наборов данных, представляющих сведения о сотрудниках (ввод завершится, когда вы получите
"employees_done"). Для каждого сотрудника будут указаны:- ID сотрудника (строка)
- Имя (строка)
- Отдел (строка)
- Зарплата (строка, которую нужно преобразовать в целое число)
- Стаж работы в годах (строка, которую нужно преобразовать в целое число)
- Считать строку с ID сотрудника, которого нужно найти
- Создать вложенную карту Map, где ID каждого сотрудника является ключом, а значением — другая карта Map со сведениями о сотруднике
- Получить и отобразить сведения об определённом сотруднике с помощью доступа к вложенной карте
- Рассчитать статистику по отделам и вывести отчёт о справочнике сотрудников точно в формате, показанном ниже
Например, если название компании — "TechCorp Solutions", данные о сотрудниках включают "EMP001" с именем "Alice Johnson", отделом "Engineering", зарплатой 75000, стажем 5, "EMP002" с именем "Bob Smith", отделом "Marketing", зарплатой 60000, стажем 3, "EMP003" с именем "Carol Davis", отделом "Engineering", зарплатой 80000, стажем 7, а ID сотрудника для поиска — "EMP001", программа должна вывести:
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 successfullyЕсли название компании — "Global Industries", данные о сотрудниках включают "E100" с именем "David Wilson", отделом "Sales", зарплатой 55000, стажем 4, "E101" с именем "Emma Brown", отделом "HR", зарплатой 65000, стажем 6, а ID сотрудника для поиска — "E101", программа должна вывести:
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 successfullyЕсли название компании — "StartupHub", данные о сотрудниках включают "S001" с именем "Frank Miller", отделом "Development", зарплатой 70000, стажем 2, "S002" с именем "Grace Lee", отделом "Design", зарплатой 58000, стажем 3, "S003" с именем "Henry Chen", отделом "Development", зарплатой 72000, стажем 4, "S004" с именем "Ivy Taylor", отделом "Marketing", зарплатой 62000, стажем 5, а ID сотрудника для поиска — "S003", программа должна вывести:
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 successfullyПрограмма должна создать структуру вложенной карты Map, где во внешней карте в качестве ключей используются ID сотрудников, а каждое значение — это внутренняя карта с ключами "name", "department", "salary" и "experience". Используйте доступ к вложенной карте с двойными квадратными скобками, чтобы получить сведения об определённом сотруднике. Подсчитайте количество сотрудников в каждом отделе и рассчитайте среднюю зарплату, разделив общую сумму зарплат на количество сотрудников. Формат ввода: название компании, затем наборы из пяти значений (ID сотрудника, имя, отдел, зарплата, стаж), заканчивающиеся на "employees_done", после чего указывается ID сотрудника для поиска.
Попробуйте сами
import 'dart:io';
void main() {
// Считать название компании
String? companyName = stdin.readLineSync();
// Инициализировать вложенную карту для справочника сотрудников
Map<String, Map<String, dynamic>> employeeDirectory = {};
// Считывать данные сотрудников до "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();
// Преобразовать зарплату и стаж в целые числа
int salary = int.parse(salaryStr!);
int experience = int.parse(experienceStr!);
// TODO: Создать вложенную структуру карт для каждого сотрудника и добавить её в справочник
}
// Считать ID сотрудника для поиска
String? lookupId = stdin.readLineSync();
// TODO: Напишите ниже код, который позволит:
// 1. Вывести название компании и справочник сотрудников
// 2. Найти и вывести сведения о конкретном сотруднике
// 3. Рассчитать статистику по отделам
// 4. Рассчитать среднюю зарплату
// 5. Вывести полный отчёт в требуемом формате
}В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Логика и управление потоком
1Продвинутая работа со списками
Свойства списка: first и lastСостояние списка: isEmpty и isNotEmptyРазворот спискаДобавление в список: insertУдаление из списка: removeWhereПоиск в списке: indexOfСортировка спискаПеремешивание спискаИтоги — Органайзер списков4Продвинутая работа с Map
Итерация по MapПроверка ключей и значенийСвойства Map: keys и valuesУсловное добавление: putIfAbsentУдаление записей из MapВложенные MapИтоги — Обновление инвентаря2Функциональные операции со списками
Преобразование с помощью 'map'Фильтрация с помощью 'where'Использование '.toList()'Проверка условий с помощью 'any'Условия с 'every'Поиск с помощью 'firstWhere'Повторение — фильтрация данных5Проект: Калькулятор корзины
Настройка проектаДобавление товаров в корзину3Множества
Что такое множество?Создание множестваДобавление и удаление элементовПроверка наличия элементов в множествеПреобразование списка в множествоОбъединение множествПересечение множествРазность множествИтоги: уникальный список гостейПотренируйтесь самостоятельно: Онлайн-компилятор Dart