Scala for Backend Engineering & Functional Programming · درس

العمليات الوظيفية على المجموعات

أتقن العمليات الوظيفية الشائعة مثل map وfilter وfold وreduce لتحويل البيانات

الدرس 2 من 311 خطوة

العمليات الوظيفية على المجموعات درس مجاني في Scala for Backend Engineering & Functional Programming على CoddyKit. هذا هو الدرس 2 من أصل 3. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Scala for Backend Engineering & Functional Programming، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Scala for Backend Engineering & Functional Programming 3 دروس في المجموع.

العمليات الوظيفية: لماذا نستخدمها؟

تساعد العمليات الوظيفية على المجموعات في تحويل البيانات ودمجها دون تغيير المجموعة الأصلية. ويعزز هذا الأسلوب عدم القابلية للتغيير، ويجعل الشيفرة أسهل في القراءة والاختبار.

سنستكشف العمليات الأساسية مثل map وfilter وreduce وfold.

التحويل باستخدام `map`

تطبّق عملية map دالةً على كل عنصر في مجموعة، وتعيد مجموعة جديدة بالنتائج المحوّلة. وتبقى المجموعة الأصلية دون تغيير.

جرّب تشغيل المثال التالي:

object Main {
  def main(args: Array[String]): Unit = {
    val numbers = List(1, 2, 3, 4)
    val doubled = numbers.map(n => n * 2)
    println(s"Original: $numbers")
    println(s"Doubled: $doubled")
  }
}

`map` مع أنواع مختلفة

تتسم map بمرونة كبيرة! إذ يمكنكم تحويل العناصر إلى نوع مختلف تمامًا. في هذا المثال، نحوّل الأعداد إلى سلاسل نصية أو نحصل على أطوال السلاسل النصية.

لاحظوا أن النتيجة هي List[Int]، رغم أن الإدخال كان List[String].

object Main {
  def main(args: Array[String]): Unit = {
    val names = List("Alice", "Bob", "Charlie")
    val lengths = names.map(name => name.length)
    println(s"Names: $names")
    println(s"Lengths: $lengths")
  }
}

الاختيار باستخدام `filter`

تنشئ عملية filter مجموعة جديدة تحتوي فقط على العناصر التي تستوفي شرطًا معينًا (دالة predicate). وهي تستبعد العناصر غير المطلوبة.

لنعثر على الأعداد الزوجية:

object Main {
  def main(args: Array[String]): Unit = {
    val numbers = List(1, 2, 3, 4, 5, 6)
    val evens = numbers.filter(n => n % 2 == 0)
    println(s"Original: $numbers")
    println(s"Evens: $evens")
  }
}

أمثلة إضافية على `filter`

يمكنكم استخدام أي تعبير منطقي شرطًا للتصفية. لِنُصفِّ قائمة من الكلمات بحيث نحتفظ فقط بالكلمات التي يزيد طولها على 4 أحرف.

object Main {
  def main(args: Array[String]): Unit = {
    val words = List("apple", "cat", "banana", "dog", "elephant")
    val longWords = words.filter(w => w.length > 4)
    println(s"Words: $words")
    println(s"Long words: $longWords")
  }
}

الدمج باستخدام `reduce`

تجمع عملية reduce جميع عناصر المجموعة في نتيجة واحدة. وهي تأخذ عملية ثنائية (دالة تستقبل وسيطين وتعيد وسيطًا واحدًا) وتطبّقها تراكميًا.

نجمع هنا جميع العناصر:

object Main {
  def main(args: Array[String]): Unit = {
    val numbers = List(1, 2, 3, 4)
    val sum = numbers.reduce((a, b) => a + b)
    println(s"Numbers: $numbers")
    println(s"Sum: $sum")
  }
}

استخدام `reduce` لحساب حاصل الضرب والقيمة العظمى

يمكن استخدام reduce لإجراء عمليات تجميع مختلفة. إذ يمكننا حساب حاصل ضرب الأعداد أو العثور على القيمة العظمى.

ملاحظة: ستُطلق reduce خطأً عند استخدامها مع مجموعة فارغة.

object Main {
  def main(args: Array[String]): Unit = {
    val numbers = List(1, 5, 2, 8)
    val product = numbers.reduce((a, b) => a * b)
    val maxNum = numbers.reduce((a, b) => if (a > b) a else b)
    println(s"Numbers: $numbers")
    println(s"Product: $product")
    println(s"Max: $maxNum")
  }
}

`fold`: قوة القيمة الابتدائية

تشبه fold العملية reduce، لكن مع اختلاف مهم: فهي تتلقى قيمة ابتدائية (تُسمّى أيضًا «المجمّع»). وهذا يجعلها آمنة عند التعامل مع المجموعات الفارغة، كما يتيح لها إرجاع أنواع مختلفة من النتائج.

لنجمع الأعداد بدءًا من 10:

object Main {
  def main(args: Array[String]): Unit = {
    val numbers = List(1, 2, 3)
    // foldLeft(initialValue)(operation)
    val sumWithInitial = numbers.foldLeft(10)((acc, n) => acc + n)
    println(s"Numbers: $numbers")
    println(s"Sum (starting from 10): $sumWithInitial")
  }
}

الاتجاه: `foldLeft` مقابل `foldRight`

توفر Scala العمليتين foldLeft وfoldRight. ويختلفان في ترتيب معالجة العناصر وكيفية تمرير المجمّع.

  • foldLeft(initial)(op): تعالج العناصر من اليسار إلى اليمين.
  • foldRight(initial)(op): تعالج العناصر من اليمين إلى اليسار.

في عمليات مثل دمج السلاسل النصية، يكون للاتجاه أهمية!

object Main {
  def main(args: Array[String]): Unit = {
    val chars = List('a', 'b', 'c')
    val leftFold = chars.foldLeft("")((acc, c) => acc + c)
    val rightFold = chars.foldRight("")((c, acc) => acc + c)
    println(s"Chars: $chars")
    println(s"foldLeft: $leftFold") // Output: abc
    println(s"foldRight: $rightFold") // Output: abc (due to string append order)

    // Example where order matters: (acc, char) => char + acc
    val rightFoldReversed = chars.foldRight("")((c, acc) => c + acc)
    println(s"foldRight (char + acc): $rightFoldReversed") // Output: abc

    // A common example where order matters is for operations like subtraction or division, but string concatenation also shows it.
  }
}

اختبار العمليات الوظيفية

تأملوا مقطع شيفرة Scala التالي:

val data = List(10, 20, 30, 40)
val result1 = data.map(x => x / 10)
val result2 = data.filter(x => x > 25)
val result3 = data.reduce((a, b) => a + b)

أي العبارات التالية صحيحة بشأن النتائج؟

مراجعة: قوة العمليات الوظيفية

لقد أتقنتم العمليات الوظيفية الأساسية!

  • map تحوّل كل عنصر.
  • filter تختار العناصر بناءً على شرط.
  • reduce تجمع العناصر في نتيجة واحدة (وتتطلب مجموعة غير فارغة).
  • fold تجمع العناصر مع قيمة ابتدائية (وهي آمنة عند التعامل مع المجموعات الفارغة).

تُعد هذه العمليات أساسية لكتابة شيفرة Scala موجزة وغير قابلة للتغيير وقوية. بعد ذلك، سنستكشف معالجة الأخطاء بطريقة متينة باستخدام Option وTry وEither.

البدء مجانًا

تعلم Scala مع معلم ذكاء اصطناعي — مجانًا

اكتب وقم بتشغيل أكوادك الفعلية في المتصفح، واحصل على مساعدة فورية من معلم ذكاء اصطناعي متاح 24/7، واستمر من حيث توقفت على الويب أو في التطبيق.

الدورات
39
الدروس
143

الأسئلة الشائعة

هل درس «العمليات الوظيفية على المجموعات» مجاني؟

نعم — نص درس «العمليات الوظيفية على المجموعات» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Scala for Backend Engineering & Functional Programming، انتقل إلى CoddyKit PRO. تتضمن دورة Scala for Backend Engineering & Functional Programming 3 دروس في المجموع.

ماذا ستتعلم في «العمليات الوظيفية على المجموعات»؟

أتقن العمليات الوظيفية الشائعة مثل map وfilter وfold وreduce لتحويل البيانات تتمرن على Scala for Backend Engineering & Functional Programming مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Scala for Backend Engineering & Functional Programming؟

لا تُشترط خبرة سابقة. Scala for Backend Engineering & Functional Programming على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 3.

كم من الوقت يستغرق درس «العمليات الوظيفية على المجموعات»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Scala for Backend Engineering & Functional Programming هذا؟

نعم. كل درس في Scala for Backend Engineering & Functional Programming يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. استكشاف معمّق للمجموعات غير القابلة للتغيير
  2. العمليات الوظيفية على المجموعات
  3. Option وTry وEither لمعالجة الأخطاء
← العودة إلى Scala for Backend Engineering & Functional Programming