0Pricing
Learn Rust Coding · درس

map وfilter وcollect

تحويل المتتاليات

map وfilter وcollect درس مجاني في Learn Rust Coding على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Learn Rust Coding، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Learn Rust Coding 4 دروس في المجموع.

تحويل التسلسلات

تنجز ثلاث دوال معظم العمل في مسارات المكرّرات: تحوّل map كل عنصر، وتُبقي filter بعض العناصر، وتجمع collect النتائج في مجموعة.

وتستبدل هذه الدوال معًا العديد من الحلقات اليدوية بسلاسل قصيرة سهلة القراءة.

map: إدخال واحد وإخراج واحد

تطبّق map closure على كل عنصر وتنتج القيمة المحوَّلة. ويبقى عدد العناصر نفسه؛ ولا تتغير إلا قيمها.

وهي كسولة، لذا لا تُنفَّذ closure إلا عند استهلاك المكرّر.

fn main() {
    let nums = vec![1, 2, 3];
    let doubled: Vec<i32> = nums.iter().map(|x| x * 2).collect();
    println!("{:?}", doubled);
}

يمكن لـ map تغيير النوع

لا يلزم أن يطابق نوع إخراج map نوع الإدخال. ففي هذا المثال نحوّل الأرقام إلى سلاسل نصية.

وهذا يجعل map مناسبة تمامًا لتحويل البيانات من هيئة إلى أخرى.

fn main() {
    let nums = vec![1, 2, 3];
    let labels: Vec<String> = nums.iter().map(|x| format!("n{}", x)).collect();
    println!("{:?}", labels);
}

filter: الاحتفاظ بما تريده

تستقبل filter closure تعيد قيمة من النوع bool. وتُبقى العناصر التي تعيد لها true، بينما تُحذف بقية العناصر.

وتستقبل closure مرجعًا، لذا غالبًا ما تلغي الإشارة المرجعية باستخدام * أو تستخدم مطابقة الأنماط.

fn main() {
    let nums = vec![1, 2, 3, 4, 5, 6];
    let evens: Vec<i32> = nums.into_iter().filter(|x| x % 2 == 0).collect();
    println!("{:?}", evens);
}

تسلسل map وfilter

يمكنك تسلسل المحوّلات بحرية. ويهم الترتيب، إذ يمر كل عنصر عبر السلسلة من الأعلى إلى الأسفل.

في هذا المثال نُبقي الأعداد الزوجية، ثم نربّع العناصر المتبقية.

fn main() {
    let result: Vec<i32> = (1..=6)
        .filter(|x| x % 2 == 0)
        .map(|x| x * x)
        .collect();
    println!("{:?}", result);
}

جمع النتائج في Vec

تستهلك collect مكرّرًا وتنشئ مجموعة. وبما أن أنواعًا عديدة من المجموعات ممكنة، فعادةً ما تحدد نوع القيمة الهدف.

تُعدّ صياغة turbofish ‏collect::<Vec<_>>() بديلًا عن تحديد نوع المتغير.

fn main() {
    let squares = (1..=4).map(|x| x * x).collect::<Vec<i32>>();
    println!("{:?}", squares);
}

جمع النتائج في String

لا تقتصر collect على المتجهات. إذ يمكن لمكرّر من char أن يجمع نتائجه في String.

وتستخدم Rust نوع القيمة الهدف لتحديد كيفية تجميع العناصر.

fn main() {
    let shouted: String = "hello".chars().map(|c| c.to_ascii_uppercase()).collect();
    println!("{}", shouted);
}

جمع النتائج في HashMap

يمكن لمكرّر من الصفوف التي تتكون من مفتاح وقيمة أن يجمع نتائجه في HashMap. اجمع العناصر في أزواج باستخدام zip أو أنشئ الصفوف داخل map.

وهذه طريقة واضحة لإنشاء عمليات بحث من تسلسلين متوازيين.

use std::collections::HashMap;

fn main() {
    let map: HashMap<i32, i32> = (1..=3).map(|x| (x, x * x)).collect();
    println!("{:?}", map.get(&2));
}

دمج الدوال الثلاث

يُقرأ المسار المعتاد كأنه جملة: خذ العناصر، ثم صفِّها، ثم حوّلها، ثم اجمعها.

في هذا المثال نُبقي الكلمات التي يزيد طولها على ثلاثة أحرف ونحوّلها إلى أحرف كبيرة.

fn main() {
    let words = vec!["hi", "rust", "go", "code"];
    let kept: Vec<String> = words
        .into_iter()
        .filter(|w| w.len() > 3)
        .map(|w| w.to_uppercase())
        .collect();
    println!("{:?}", kept);
}

filter_map: التصفية والتحويل معًا

تطبّق filter_map closure تعيد Option. ويُبقى Some(v) وتُزال عنه التغلفة، بينما يُحذف None.

وتتألق هذه الدالة عند التحليل، حيث قد تكون بعض المدخلات غير صالحة.

fn main() {
    let inputs = vec!["1", "two", "3"];
    let nums: Vec<i32> = inputs
        .into_iter()
        .filter_map(|s| s.parse::<i32>().ok())
        .collect();
    println!("{:?}", nums);
}

لماذا ينجح هذا النمط

تتسم مسارات map/filter/collect بأنها وصفية: فهي توضّح ما تريده، لا كيفية التكرار. كما تتجنب أخطاء تجاوز الحد وحالة التغيير الوسيطة.

وبفضل الكسل، لا تُنشأ متجهات مؤقتة بين الخطوات.

تحقق سريع

اختبر معلوماتك عن تحويل التسلسلات.

مراجعة

يمكنك الآن إنشاء مسارات مكرّرات حقيقية:

  • تحوّل map كل عنصر، وقد تغيّر نوعه
  • تُبقي filter العناصر التي يكون الشرط الخاص بها true
  • تجمع collect النتائج في Vec وString وHashMap وغيرها
  • تُجري filter_map التصفية والتحويل في خطوة واحدة باستخدام Option

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

هل درس «map وfilter وcollect» مجاني؟

نعم — نص درس «map وfilter وcollect» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Learn Rust Coding، انتقل إلى CoddyKit PRO. تتضمن دورة Learn Rust Coding 4 دروس في المجموع.

ماذا ستتعلم في «map وfilter وcollect»؟

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

هل أحتاج إلى خبرة سابقة لأبدأ Learn Rust Coding؟

لا تُشترط خبرة سابقة. Learn Rust Coding على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.

كم من الوقت يستغرق درس «map وfilter وcollect»؟

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

هل يمكنني كتابة وتشغيل أكواد في درس Learn Rust Coding هذا؟

نعم. كل درس في Learn Rust Coding يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

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

  1. سمة Iterator
  2. map وfilter وcollect
  3. المهايئات والمستهلكات
  4. المكررات المخصصة
← العودة إلى Learn Rust Coding