المصفوفات والقواميس في Swift: Array و Dictionary و Set
قائمة جهات الاتصال، والأغاني المفضلة، وإعدادات التطبيق: كلها مجموعات من البيانات. Swift تقدم ثلاثة أنواع أساسية للمجموعات: المصفوفة المرتبة، والقاموس بالمفاتيح، والمجموعة بلا تكرار. وكعادتها، تضيف Swift طبقة أمان تحميك من الأخطاء الشائعة عند التعامل معها.
المصفوفة (Array)
Section titled “المصفوفة (Array)”var colors = ["أحمر", "أخضر", "أزرق"]print(colors[0])print(colors.count)أحمر3مصفوفة مرتبة، والترقيم يبدأ من صفر. و count عدد العناصر. ونوع المصفوفة هنا [String]: «مصفوفة نصوص»، وكل عناصرها يجب أن تكون من نفس النوع.
الإضافة والتعديل والحذف (المصفوفة يجب أن تكون var):
colors.append("أصفر")colors[0] = "بنفسجي"colors.remove(at: 1)print(colors)print(colors.contains("أزرق"))["بنفسجي", "أزرق", "أصفر"]trueappend: إضافة في النهاية.remove(at: 1): حذف العنصر رقم 1 («أخضر»).contains: هل القيمة موجودة؟
لو كانت المصفوفة معرّفة بـ let، سيرفض المترجم أي تعديل عليها. هكذا تحمي Swift القوائم التي لا يجب أن تتغير.
الوصول الآمن: first و last
Section titled “الوصول الآمن: first و last”ماذا لو طلبت عنصراً غير موجود؟ colors[10] في مصفوفة من 3 عناصر تُنهي التطبيق فوراً برسالة Fatal error: Index out of range. لذلك تقدم Swift طرقاً آمنة:
let empty: [String] = []print(empty.first ?? "القائمة فارغة")
if let firstColor = colors.first { print("أول لون: \(firstColor)")}القائمة فارغةأول لون: بنفسجيfirst و last تُرجعان قيمة اختيارية: العنصر إن وُجد، أو nil إن كانت المصفوفة فارغة. وتفتحها بـ ?? أو if let كما تعلمت في درس المتغيرات. و isEmpty تخبرك هل المصفوفة فارغة.
الدوال القوية: filter و map و reduce
Section titled “الدوال القوية: filter و map و reduce”let scores = [85, 92, 78, 64]
let passed = scores.filter { $0 >= 75 }print(passed)
let bonus = scores.map { $0 + 5 }print(bonus)
let total = scores.reduce(0, +)print(total)
print(scores.sorted())print(scores.sorted(by: >))print(scores.max() ?? 0)[85, 92, 78][90, 97, 83, 69]319[64, 78, 85, 92][92, 85, 78, 64]92filter: احتفظ بالعناصر التي تحقق الشرط.map: حوّل كل عنصر.reduce(0, +): اجمع العناصر بدءاً من صفر.sorted()تصاعدي، وsorted(by: >)تنازلي، وكلاهما يُرجع مصفوفة جديدة.max()اختيارية أيضاً، لأن المصفوفة الفارغة لا أكبر فيها.
تخيّل هذه الدوال مثل محطات في مصنع: filter محطة فحص الجودة ترفض القطع المعيبة، و map محطة الطلاء تغيّر كل قطعة، و reduce محطة التغليف تجمع الكل في صندوق واحد.
القاموس (Dictionary)
Section titled “القاموس (Dictionary)”أزواج مفتاح ← قيمة:
var prices = ["قلم": 5, "كراسة": 15, "مسطرة": 7]print(prices["قلم"] ?? 0)print(prices["ممحاة"] ?? 0)
prices["ممحاة"] = 3print(prices.count)504ملاحظة مهمة: قراءة قيمة من القاموس تُرجع قيمة اختيارية دائماً، لأن المفتاح قد لا يكون موجوداً. لهذا استخدمنا ?? 0. وإسناد قيمة لمفتاح جديد يضيفه، ولمفتاح موجود يعدّله.
والقاموس غير مرتب: لا تضمن Swift أي ترتيب عند طباعته أو المرور عليه. إذا احتجت ترتيباً، رتّب المفاتيح:
for item in prices.keys.sorted() { print("\(item): \(prices[item] ?? 0) جنيه")}المجموعة (Set)
Section titled “المجموعة (Set)”مثل المصفوفة، لكن بلا تكرار وبلا ترتيب:
let tags: Set = ["swift", "ios", "swift"]print(tags.count)print(tags.contains("ios"))2trueswift المكررة حُذفت تلقائياً. والمجموعة سريعة جداً في سؤال «هل هذا العنصر موجود؟»، حتى مع ملايين العناصر.
| النوع | مرتب؟ | يقبل التكرار؟ | الوصول |
|---|---|---|---|
Array |
نعم | نعم | بالرقم |
Dictionary |
لا | المفاتيح لا تتكرر | بالمفتاح |
Set |
لا | لا | فحص الوجود |
جرّب بنفسك
Section titled “جرّب بنفسك”احسب عدد مرات تكرار كل كلمة:
let words = ["تفاح", "موز", "تفاح", "عنب", "موز", "تفاح"]var counts: [String: Int] = [:]
for word in words { counts[word, default: 0] += 1}
print(counts["تفاح"] ?? 0)print(counts["موز"] ?? 0)32counts[word, default: 0] تعني: «إذا لم يكن المفتاح موجوداً، اعتبر قيمته صفراً»، وهي طريقة Swift الأنيقة للعدّ.
تحدٍّ: من مصفوفة درجات، اطبع عدد الناجحين ومتوسط درجاتهم، باستخدام filter و reduce.
أخطاء شائعة
Section titled “أخطاء شائعة”- رقم خارج حدود المصفوفة: ينهار التطبيق. استخدم
firstوlastوindicesللوصول الآمن. - نسيان أن قراءة القاموس اختيارية:
prices["قلم"] + 1خطأ ترجمة. افتح القيمة أولاً بـ??أوif let. - الاعتماد على ترتيب القاموس أو المجموعة: غير مضمون. رتّب المفاتيح عند الحاجة.
اختبر نفسك
Section titled “اختبر نفسك”سؤال
ما نوع القيمة التي تُرجعها prices["قلم"] إذا كان prices قاموساً من نوع [String: Int]؟
القراءة من القاموس اختيارية دائماً، لأن Swift لا تضمن وجود المفتاح.
سؤال
ما ناتج [5, 12, 8].filter { $0 > 6 }؟
filter يحتفظ فقط بالعناصر التي تحقق الشرط، وهما 12 و 8.
الخلاصة
Section titled “الخلاصة”Arrayمرتبة بأرقام من صفر، وappendوremove(at:)للتعديل في مصفوفةvar.firstوlastوmax()اختيارية، وتحميك من انهيار التطبيق.filterوmapوreduceوsortedتختصر الحلقات الطويلة.Dictionaryللمفاتيح والقيم، والقراءة منه اختيارية، وترتيبه غير مضمون.Setبلا تكرار، وسريعة في فحص وجود العناصر.