セットへの追加
CoddyのGOジャーニー「論理とフロー」セクションの一部 — レッスン 33/68。
セットを作成したので、次のステップはそこに要素を追加する方法を学ぶことです。Goのセットは実際には内部でマップであるため、セットに要素を追加することは、マップにキーを追加することと同じです。
セットに要素を追加するには、新しいキーに空の構造体の値を割り当てるだけです:
colors["yellow"] = struct{}{}struct{}{} 構文は、空の構造体リテラルを作成します。最初の struct{} は型を指定し、2番目の {} はそれを初期化します。これは、Goでセット(集合)に要素を追加する標準的な方法です。
このアプローチの利点は、同じ要素を再度追加しようとしても、既存のエントリを単に上書きするだけで、セットの一意性が維持されることです。
注意点として、この代入において struct{}{} は唯一の有効な構文です。型名なしで {} とだけ記述すると、コンパイルエラー missing type in composite literal が発生します。マップリテラルの外でマップのキーに値を代入する場合、型は常に明示的に指定する必要があります。
セットへの要素の追加は、Goの効率的なマップ実装を活用しながら、一意のアイテムを追跡するための真のセットの動作を提供し、高速かつ簡単に行えます。
チャレンジ
簡単Goのセット(集合)のイディオムを使用して、開発者の技術的能力を管理するスキル追跡システムを構築してください。このチャレンジでは、重複を防ぎ、学習の進捗を追跡しながら、新しいスキルをセットに追加する方法を学びます。
2つの入力を受け取ります:
- 期待されるスキル数を表す文字列(例:
"5") - これは参照用です - カンマで区切られたスキルを含む文字列(例:
"Go,Docker,Kubernetes,Go,React,Docker,Python")
あなたのタスクは以下の通りです:
- Goのイディオムである
map[string]struct{}を使用して、一意の技術スキルを保存するセットを作成します - 3つの初期スキル
"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 パッケージを使用してください。追加する前にスキルが既に存在するかどうかを確認するには、comma 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) を使用して進捗の概要を計算し、表示する
// 完全なスキルセット内のすべてのスキルをリストする(一貫した出力のためにソートを検討してください)
}このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。