Добавление элементов в множество
Часть раздела Логика и управление потоком путешествия по GO на Coddy. Урок 33 из 68.
Теперь, когда вы создали множество, следующий шаг — узнать, как добавлять в него элементы. Поскольку множество в Go на самом деле реализовано на основе карты, добавление элемента в множество ничем не отличается от добавления ключа в карту.
Чтобы добавить элемент в набор, просто присвой пустое значение структуры новому ключу:
colors["yellow"] = struct{}{}Синтаксис struct{}{} создаёт литерал пустой структуры. Первый struct{} задаёт тип, а второй {} инициализирует его. Это стандартный способ добавлять элементы в множество в Go.
Преимущество такого подхода в том, что если попытаться добавить тот же элемент ещё раз, он просто перезапишет существующую запись, сохраняя свойство уникальности множества.
Обрати внимание: struct{}{} — единственный допустимый синтаксис для этого присваивания: если написать только {}, не указав имя типа, возникнет ошибка компиляции: missing type in composite literal. При присваивании значения ключу карты вне литерала карты тип всегда нужно указывать явно.
Добавлять элементы в множество быстро и просто: вы используете эффективную реализацию map в Go и получаете полноценное поведение множества для отслеживания уникальных элементов.
Задание
ЛегкоСоздайте систему отслеживания навыков, которая управляет техническими навыками разработчика с помощью идиомы множества в Go. В этом задании показано, как добавлять новые навыки во множество, предотвращая дублирование и отслеживая прогресс обучения.
Вам будут предоставлены два входных значения:
- Строка, представляющая ожидаемое количество навыков (например,
"5") — только для справки - Строка со списком навыков, разделённых запятыми (например,
"Go,Docker,Kubernetes,Go,React,Docker,Python")
Ваша задача:
- Создать множество с помощью идиомы Go
map[string]struct{}для хранения уникальных технических навыков - Инициализировать множество тремя начальными навыками:
"Programming","Problem Solving"и"Communication" - Разобрать входную строку, разделив её по запятым, чтобы получить отдельные названия навыков
- Обработать все навыки из строки, разделённой запятыми (перебрать весь срез, не используя параметр количества)
- Добавить каждый навык из входных данных во множество, используя
struct{}{}в качестве значения - Вывести результаты обработки, печатая каждый навык по мере его обработки:
- Если навык новый для множества:
"Learning new skill: [skill]" - Если навык уже есть во множестве:
"Already mastered: [skill]"
- Если навык новый для множества:
- После обработки всех навыков вывести сводку прогресса:
"Skills processed: [total_processed]"— используйте длину среза навыков"New skills learned: [new_skills_count]""Total skills mastered: [total_unique_skills]"
- Наконец, перечислить все навыки в наборе навыков разработчика:
- Заголовок:
"Complete skill set:" - Каждый навык на отдельной строке:
"✓ [skill]"
- Заголовок:
Важно: Используйте range, чтобы перебрать все навыки в срезе, а не параметр количества. Количество предоставлено для справки, но не должно управлять циклом. Используйте пакет strings, чтобы разделить входную строку. Чтобы проверить, существует ли навык, прежде чем добавлять его, используйте идиому с запятой и ok: _, exists := skillSet[skill]. В этом задании показано, как добавление элементов во множество Go автоматически обеспечивает уникальность и при этом позволяет быстро проверять наличие элемента.
Попробуйте сами
package main
import (
"fmt"
"sort"
"strconv"
"strings"
)
func main() {
// Считайте входные данные
var countStr string
var skillsStr string
fmt.Scanln(&countStr)
fmt.Scanln(&skillsStr)
// Преобразуйте строку с количеством в целое число (только для справки — в цикле не используется)
_, _ = strconv.Atoi(countStr)
// Инициализируйте набор навыков начальными навыками
skillSet := map[string]struct{}{
"Programming": struct{}{},
"Problem Solving": struct{}{},
"Communication": struct{}{},
}
// Разделите строку навыков на отдельные навыки
skills := strings.Split(skillsStr, ",")
// TODO: Напишите свой код ниже
// Обработайте каждый навык, используя range для перебора ВСЕХ навыков в срезе
// Используйте идиому comma ok: _, exists := skillSet[skill]
// Добавляйте новые навыки с помощью: skillSet[skill] = struct{}{}
// Выведите результаты обработки каждого навыка
// Вычислите и выведите сводку прогресса с помощью len(skills)
// Выведите все навыки из полного набора навыков (для единообразия вывода можно использовать сортировку)
}В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Логика и управление потоком
1Продвинутое управление потоком
Оператор switch с `fallthrough`Выход из вложенных цикловПереход к следующей итерации конкретного циклаОператор `goto`Повторение: расширенное управление циклами4Проект: простой список задач
Настройка проектаДобавление задачи2Структуры и методы
Определение методов для структурПолучатели-значенияПолучатели-указателиВыбор получателейМетоды и функцииПовторение: поведение структур5Карты: подробный разбор
Карты структурУказатели как значения картПроверка карт на nilСравнение картПовторение — счётчик частоты слов8Проект: простой складской учёт
Обзор проектаПроверка запасов3Интерфейсы (основы)
Что такое интерфейс?Определение интерфейсаРеализация интерфейсаИспользование типов интерфейсовПустой интерфейсУтверждения типовПереключатель типовПовторение — формы и поведение6Идиоматический Go: множества
Идиома множества в GoСоздание множестваДобавление элементов в множествоПроверка наличия элементаУдаление элемента из множестваПеребор элементов множестваПовторение — уникальные имена пользователейПотренируйтесь самостоятельно: Онлайн-компилятор Go