الطي والاختزال
foldLeft وreduce
الطي والاختزال درس مجاني في Scala for Backend Engineering & Functional Programming على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Scala for Backend Engineering & Functional Programming، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Scala for Backend Engineering & Functional Programming 4 دروس في المجموع.
دمج العناصر في قيمة واحدة
تحتاجون أحيانًا إلى دمج جميع عناصر مجموعة في قيمة واحدة، مثل المجموع أو التسلسل. توفّر Scala الدوال fold وfoldLeft وfoldRight وreduce لهذا الغرض.
object Main {
def main(args: Array[String]): Unit = {
val nums = List(1, 2, 3, 4)
println(nums.sum)
println(nums.product)
}
}reduce: الدمج دون قيمة ابتدائية
تدمج reduce العناصر زوجيًا باستخدام دالة ثنائية. وهي تتطلب وجود عنصر واحد على الأقل، وإلا فستطرح استثناءً.
object Main {
def main(args: Array[String]): Unit = {
val nums = List(1, 2, 3, 4)
val total = nums.reduce((a, b) => a + b)
println(total)
val max = nums.reduce((a, b) => if (a > b) a else b)
println(max)
}
}foldLeft: الدمج باستخدام قيمة ابتدائية
تأخذ foldLeft قيمة ابتدائية ودالة. وهي آمنة مع المجموعات الفارغة، إذ تُعيد القيمة الابتدائية، كما تسمح بأن يختلف نوع النتيجة عن نوع العناصر.
الصيغة: xs.foldLeft(seed)((acc, x) => ...).
object Main {
def main(args: Array[String]): Unit = {
val nums = List(1, 2, 3, 4)
val sum = nums.foldLeft(0)((acc, x) => acc + x)
println(sum)
val empty = List.empty[Int].foldLeft(0)(_ + _)
println(empty)
}
}نمط المُجمِّع
في عملية الطي، تكون الوسيطة الأولى هي المُجمِّع الذي يحمل النتيجة الحالية، بينما تكون الوسيطة الثانية هي العنصر الحالي. وفي كل خطوة، يُحدَّث المُجمِّع.
object Main {
def main(args: Array[String]): Unit = {
val words = List("Scala", "is", "great")
val sentence = words.foldLeft("")((acc, w) => acc + w + " ")
println(sentence.trim)
}
}يمكن أن يختلف نوع النتيجة
من الميزات القوية في foldLeft أن نوع المُجمِّع يمكن أن يختلف عن نوع العناصر. نطوي هنا قائمة من الأعداد لتكوين String.
object Main {
def main(args: Array[String]): Unit = {
val nums = List(1, 2, 3)
val joined = nums.foldLeft("nums:")((acc, n) => acc + " " + n)
println(joined)
}
}foldRight: من اليمين
تعالج foldRight العناصر من اليمين إلى اليسار. ويكون المُجمِّع هو الوسيطة الثانية: (x, acc) => .... ويؤثر الاتجاه في العمليات غير التبديلية.
object Main {
def main(args: Array[String]): Unit = {
val nums = List(1, 2, 3, 4)
val left = nums.foldLeft("")((acc, x) => acc + x)
val right = nums.foldRight("")((x, acc) => acc + x)
println("foldLeft: " + left)
println("foldRight: " + right)
}
}الطي من اليسار أو اليمين والأداء
تستخدم foldLeft الاستدعاء الذاتي النهائي، وتكون آمنة من امتلاء المكدس عند التعامل مع القوائم الكبيرة. أما foldRight مع List فقد تؤدي إلى امتلاء المكدس عند إدخال قيم كبيرة جدًا. لذا يُفضَّل استخدام foldLeft ما لم يفرض ترتيب العناصر خلاف ذلك.
object Main {
def main(args: Array[String]): Unit = {
val big = (1 to 100000).toList
val total = big.foldLeft(0L)((acc, x) => acc + x)
println(total)
}
}بناء مجموعة باستخدام fold
تتسم عمليات الطي بقدر كافٍ من العمومية بحيث يمكنها بناء مجموعات. نعكس هنا قائمةً بإضافة كل عنصر إلى بداية قائمة المُجمِّع.
object Main {
def main(args: Array[String]): Unit = {
val nums = List(1, 2, 3, 4)
val reversed = nums.foldLeft(List.empty[Int])((acc, x) => x :: acc)
println(reversed)
}
}استخدام reduceOption بأمان
نظرًا إلى أن reduce تفشل مع المجموعات الفارغة، تُعيد reduceOption قيمة من النوع Option بدلًا من ذلك: Some(result) عندما لا تكون المجموعة فارغة، وNone عندما تكون فارغة.
object Main {
def main(args: Array[String]): Unit = {
println(List(3, 1, 4).reduceOption(_ + _))
println(List.empty[Int].reduceOption(_ + _))
}
}fold: صيغة متماثلة
تشبه fold الدالة foldLeft، لكن يجب أن يكون نوع المُجمِّع مطابقًا لنوع العناصر. وغالبًا ما تُستخدم مع المجموعات المتوازية.
object Main {
def main(args: Array[String]): Unit = {
val nums = List(1, 2, 3, 4)
val total = nums.fold(0)(_ + _)
println(total)
}
}العد باستخدام foldLeft
يمكن لعمليات الطي حساب نتائج أكثر تعقيدًا، مثل عدّ عدد العناصر التي تستوفي شرطًا، وذلك في مرور واحد.
object Main {
def main(args: Array[String]): Unit = {
val nums = List(4, 7, 2, 9, 6, 1)
val evenCount = nums.foldLeft(0)((acc, x) => if (x % 2 == 0) acc + 1 else acc)
println(s"even numbers: $evenCount")
}
}اختبار سريع
ما الفرق الأساسي بين reduce وfoldLeft؟
مراجعة
لقد تعلّمتم الطي والاختزال:
reduce— دمج زوجي دون قيمة ابتدائية، وتفشل إذا كانت المجموعة فارغةreduceOption— صيغة آمنة تُعيدOptionfoldLeft— قيمة ابتدائية ومُجمِّع، آمنة من امتلاء المكدس، ونوع نتيجة مرنfoldRight— من اليمين إلى اليسار، مع الانتباه إلى المكدس عند التعامل مع القوائم الكبيرة- يمكن لعمليات الطي حتى بناء مجموعات جديدة
تعلم Scala مع معلم ذكاء اصطناعي — مجانًا
اكتب وقم بتشغيل أكوادك الفعلية في المتصفح، واحصل على مساعدة فورية من معلم ذكاء اصطناعي متاح 24/7، واستمر من حيث توقفت على الويب أو في التطبيق.
- الدورات
- 39
- الدروس
- 143
الأسئلة الشائعة
هل درس «الطي والاختزال» مجاني؟
نعم — نص درس «الطي والاختزال» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Scala for Backend Engineering & Functional Programming، انتقل إلى CoddyKit PRO. تتضمن دورة Scala for Backend Engineering & Functional Programming 4 دروس في المجموع.
ماذا ستتعلم في «الطي والاختزال»؟
foldLeft وreduce تتمرن على Scala for Backend Engineering & Functional Programming مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Scala for Backend Engineering & Functional Programming؟
لا تُشترط خبرة سابقة. Scala for Backend Engineering & Functional Programming على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.
كم من الوقت يستغرق درس «الطي والاختزال»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Scala for Backend Engineering & Functional Programming هذا؟
نعم. كل درس في Scala for Backend Engineering & Functional Programming يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- List وVector وSet وMap
- التحويلات
- الطي والاختزال
- التجميع والترتيب