الإضافة إلى مجموعة
جزء من قسم Logic & Flow في رحلة GO على Coddy — الدرس 33 من 68.
الآن بعد أن قمت بإنشاء مجموعة (set)، فإن الخطوة التالية هي تعلم كيفية إضافة عناصر إليها. وبما أن مجموعة Go هي في الواقع خريطة (map) في جوهرها، فإن إضافة عنصر إلى مجموعة يماثل تماماً إضافة مفتاح إلى خريطة.
لإضافة عنصر إلى مجموعتك، ما عليك سوى تعيين قيمة الهيكل (struct) الفارغة لمفتاح جديد:
colors["yellow"] = struct{}{}بناء الجملة struct{}{} ينشئ قيمة هيكلية فارغة (empty struct literal). يحدد الـ struct{} الأول النوع، بينما يقوم الـ {} الثاني بتهيئته. هذه هي الطريقة القياسية لإضافة عناصر إلى مجموعة (set) في لغة Go.
يكمن جمال هذا النهج في أنك إذا حاولت إضافة نفس العنصر مرة أخرى، فإنه ببساطة يكتب فوق الإدخال الموجود، مما يحافظ على خاصية التفرد للمجموعة.
لاحظ أن struct{}{} هو الصيغة الوحيدة الصالحة لهذا التعيين — حيث أن كتابة {} فقط بدون اسم النوع تؤدي إلى خطأ في التجميع (compilation error): missing type in composite literal. يجب دائمًا توفير النوع بشكل صريح عند تعيين قيمة لمفتاح خريطة (map key) خارج تعبير الخريطة (map literal).
إضافة العناصر إلى المجموعة عملية سريعة ومباشرة، حيث تستفيد من تنفيذ الخريطة (map) الفعال في لغة Go مع منحك سلوك المجموعة الحقيقي لتتبع العناصر الفريدة.
التحدي
سهلقم ببناء نظام لتتبع المهارات يدير القدرات التقنية للمطور باستخدام أسلوب الـ set في لغة Go. يوضح هذا التحدي كيفية إضافة مهارات جديدة إلى مجموعة (set) مع منع التكرار وتتبع تقدم التعلم.
ستتلقى مدخلين:
- سلسلة نصية تمثل العدد المتوقع للمهارات (على سبيل المثال،
"5") - وهذا كمرجع فقط - سلسلة نصية تحتوي على مهارات مفصولة بفاصلة (على سبيل المثال،
"Go,Docker,Kubernetes,Go,React,Docker,Python")
مهمتك هي:
- إنشاء مجموعة (set) باستخدام أسلوب Go المتمثل في
map[string]struct{}لتخزين المهارات التقنية الفريدة - تهيئة المجموعة بثلاث مهارات أساسية:
"Programming"، و"Problem Solving"، و"Communication" - تحليل سلسلة المدخلات عن طريق تقسيمها عند الفواصل للحصول على أسماء المهارات الفردية
- معالجة جميع المهارات من السلسلة المفصولة بفاصلة (قم بالتكرار عبر الشريحة (slice) بالكامل، دون استخدام معامل العدد)
- لكل مهارة من المدخلات، أضفها إلى مجموعتك باستخدام
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 set تتعامل تلقائياً مع التفرد مع توفير أداء بحث سريع لاختبار العضوية.
جرّب بنفسك
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 للتكرار عبر كافة المهارات في الـ slice
// استخدم صيغة comma ok: _, exists := skillSet[skill]
// أضف مهارات جديدة باستخدام: skillSet[skill] = struct{}{}
// عرض نتائج المعالجة لكل مهارة
// حساب وعرض ملخص التقدم باستخدام len(skills)
// سرد كافة المهارات في مجموعة المهارات الكاملة (فكر في الفرز للحصول على مخرجات متسقة)
}يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس Logic & Flow
1تدفق التحكم المتقدم
جملة Switch مع `fallthrough`الخروج من الحلقات المتداخلةالاستمرار في حلقة محددةجملة `goto`ملخص - التحكم المتقدم في الحلقات2الـ Structs والميثودز (Methods)
تعريف الـ Methods على الـ Structsالـ Value Receiversالـ Pointer Receiversاختيار الـ Receiversالـ Methods مقابل الـ Functionsملخص - سلوك الـ Struct5تعمق في الـ Maps
Maps من نوع Structsالـ Pointers كقيم في الـ Mapsالتحقق من الـ Nil Mapsمقارنة الـ Mapsمراجعة - عداد تكرار الكلمات3الواجهات (الأساسيات)
ما هي الواجهة؟تعريف الواجهةتطبيق الواجهةاستخدام أنواع الواجهاتالواجهة الفارغةتأكيدات النوع (Type Assertions)تبديل النوع (Type Switch)ملخص - الأشكال والسلوكيات6أسلوب Go الاصطلاحي: المجموعات
أسلوب المجموعات في Goإنشاء مجموعةالإضافة إلى مجموعةالتحقق من العضوية في المجموعةالحذف من مجموعةالتكرار عبر عناصر المجموعةمراجعة - أسماء مستخدمين فريدة