فرز المتجهات في Rust: دليل شامل للمبتدئين مع أمثلة

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

كيفية فرز متجه في Rust: من المبتدئ إلى المحترف



تخيل: أنت تكتب برنامجًا بلغة Rust يجمع قائمة من المستخدمين - الأسماء، العمر، التقييم. البيانات تأتي بترتيب عشوائي. تحتاج إلى عرضها أبجديًا أو، على سبيل المثال، فرزها حسب العمر. مهمة مألوفة؟ إذا كنت قد ألقيت نظرة على Stack Overflow، فمن المحتمل أنك رأيت السؤال "How to sort a vector in Rust?" - لقد حصد آلاف المشاهدات. وهذا ليس من قبيل الصدفة.



الفرز في Rust هو أحد تلك الموضوعات التي قد لا يعمل فيها "مجرد استدعاء sort()" إذا كنت لا تعرف بعض التفاصيل الدقيقة. في هذه المقالة، سنستعرض جميع الطرق الشائعة لفرز المتجه: من الطريقة الأساسية sort() إلى المقارنات المخصصة والاختيار بين الفرز المستقر وغير المستقر. ستتعلم كيفية فرز متجه في Rust بشكل صحيح وسريع وبدون ذعر.



الطريقة الأساسية: sort() - عندما يكون كل شيء بسيطًا



أسهل طريقة لفرز متجه هي استخدام الطريقة sort(). إنها تعمل مع الأنواع التي تطبق trait Ord - وهذا يشمل جميع الأنواع البدائية القياسية (الأرقام، السلاسل النصية، الأحرف).



fn main() {    let mut numbers = vec![4, 2, 9, 1, 5, 6];    numbers.sort();    println!("{:?}", numbers); // الإخراج: [1, 2, 4, 5, 6, 9]}


لاحظ: المتغير numbers تم تعريفه كـ mut (قابل للتغيير). الطريقة sort() تعدل المتجه في مكانه، لذلك بدون mut لن يتم تجميع الكود. هذا خطأ نموذجي للمبتدئين - نسيان قابلية التغيير.



نفس الشيء يعمل مع السلاسل النصية:



fn main() {    let mut fruits = vec!["banana", "apple", "cherry", "date"];    fruits.sort();    println!("{:?}", fruits); // الإخراج: ["apple", "banana", "cherry", "date"]}


الفرز الافتراضي للسلاسل النصية هو معجمي (أبجديًا). إذا كنت بحاجة إلى فرز حسب الطول أو تجاهل حالة الأحرف - اقرأ القسم الخاص بالمقارنات المخصصة.



sort_unstable(): عندما تكون السرعة أهم من الترتيب



في Rust، هناك نوعان من الفرز: sort() (مستقر) و sort_unstable() (غير مستقر). الفرق هو أن الفرز المستقر يحافظ على الترتيب النسبي للعناصر المتساوية، بينما الفرز غير المستقر لا يفعل ذلك. يبدو أكاديميًا، لكنه مهم عمليًا إذا كنت تقوم بفرز هياكل معقدة وتريد الحفاظ على ترتيب الإدراج للمفاتيح المتساوية.



ومع ذلك، فإن sort_unstable() لها ميزة: إنها تعمل بشكل أسرع وتستخدم ذاكرة أقل. بالنسبة للمتجهات الكبيرة (ملايين العناصر)، يمكن أن يكون الفرق كبيرًا.



fn main() {    let mut scores = vec![85, 92, 85, 70, 92, 60];    scores.sort_unstable();    println!("{:?}", scores); // الإخراج: [60, 70, 85, 85, 92, 92]    // قد يختلف ترتيب الـ 85 والـ 92 عن الترتيب الأصلي}


متى تختار sort_unstable؟ إذا كان ترتيب العناصر المتساوية غير مهم بالنسبة لك وكنت تسعى وراء الأداء. إذا كانت القدرة على التنبؤ مهمة (على سبيل المثال، فرز جدول بعدة أعمدة)، استخدم sort().



sort_by(): المقارنات المخصصة



ماذا تفعل إذا كنت بحاجة إلى فرز متجه وفقًا لقاعدة غير قياسية؟ على سبيل المثال، الأرقام تنازليًا، السلاسل النصية حسب الطول، أو الهياكل المخصصة حسب أحد الحقول. لهذا، توجد الطريقة sort_by()، التي تأخذ إغلاقًا (closure) كمقارن.



يجب أن يُرجع المقارن Ordering - أحد الخيارات: Less أو Equal أو Greater. أسهل طريقة للحصول على هذه النتيجة هي استخدام الطرق .cmp() أو .partial_cmp().



مثال: فرز الأرقام تنازليًا.



fn main() {    let mut numbers = vec![4, 2, 9, 1, 5];    numbers.sort_by(|a, b| b.cmp(a));    println!("{:?}", numbers); // الإخراج: [9, 5, 4, 2, 1]}


لاحظ: نحن نتبادل أماكن a و b -

المدونات

توصيات الكتب