كيفية تحديد العنصر الأول والأخير في foreach؟ 3 طرق عملية

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

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

ابدأ الدورة

أول وآخر عنصر في حلقة foreach: الصداع الدائم لمطور PHP

\n\n

تخيل موقفًا: أنت تعرض قائمة منتجات في متجر إلكتروني. يجب أن يحمل المنتج الأول علامة "الأكثر مبيعًا"، والمنتج الأخير علامة "جديد". أو لنفترض أنك تقوم بإنشاء خلاصة XML حيث يجب تغليف العناصر بعلامات حاوية، ولكن فقط للعنصر الأول والأخير. كيف تفعل ذلك في PHP؟ قد تبدو المهمة بسيطة، لكنها حصدت آلاف المشاهدات وعشرات الحلول على Stack Overflow.

\n\n

لماذا تسبب هذه المهمة البسيطة ظاهريًا كل هذا الجدل؟ السبب هو أن foreach في PHP هو مكرر (iterator) لا يوفر طرقًا مدمجة لتحديد رقم التكرار. على عكس حلقة for حيث لدينا عداد $i، في foreach نتعامل فقط مع المفتاح والقيمة. وهنا يبدأ السحر: البعض يستخدم العدادات، والبعض يستخدم دوال reset() و end()، والبعض الآخر يستخدم حيلًا ذكية مع مؤشرات المصفوفة.

\n\n

في هذه المقالة، سنستعرض ثلاث طرق رئيسية لتحديد أول وآخر تكرار في foreach، ونقارن بين أدائها، وسهولة قراءتها، وموثوقيتها. ستتعرف على الطريقة الأنسب لمهمتك وكيفية تجنب الأخطاء الشائعة. هيا بنا!

\n\n

الطريقة الأولى: العداد التقليدي (الأكثر وضوحًا)

\n\n

الطريقة الأكثر بداهة هي استخدام متغير عداد ومقارنته بإجمالي عدد عناصر المصفوفة. تُعرف هذه الطريقة أحيانًا بالطريقة "التقليدية"، لكنها تعمل بدون أخطاء.

\n\n
<?php\n$items = ['تفاح', 'موز', 'كرز', 'شمام'];\n$total = count($items);\n$counter = 0;\n\nforeach ($items as $item) {\n    $counter++;\n    if ($counter === 1) {\n        echo "<strong>الأول: $item</strong><br>";\n    } elseif ($counter === $total) {\n        echo "<em>الأخير: $item</em><br>";\n    } else {\n        echo "$item<br>";\n    }\n}\n?>
\n\n

المزايا:

\n
    \n
  • منطق واضح للغاية — أي مبتدئ سيفهم الكود من النظرة الأولى.
  • \n
  • لا يعتمد على نوع مفاتيح المصفوفة (يعمل مع المصفوفات الترابطية والرقمية).
  • \n
  • سهل التعديل: تريد التحقق من التكرار الثاني أو قبل الأخير؟ فقط غيّر الشرط.
  • \n
\n\n

العيوب:

\n
    \n
  • يتطلب استدعاء count() للمصفوفة بأكملها — وهذا حمل صغير، لكنه قد يكون ملحوظًا في المصفوفات الكبيرة جدًا (ملايين العناصر).
  • \n
  • يجب ألا تنسى تهيئة العداد قبل الحلقة.
  • \n
  • إذا كانت المصفوفة فارغة، سيكون $total يساوي 0، ولن يعمل الشرط $counter === $total أبدًا (وهو منطقي، لكن المبتدئين ينسون ذلك).
  • \n
\n\n

الطريقة الثانية: استخدام reset() و end() الذكية (لعشاق الإيجاز)

\n\n

في PHP، هناك دالة reset() التي تُرجع العنصر الأول من المصفوفة، ودالة end() التي تُرجع العنصر الأخير. الحيلة هي أننا يمكننا مقارنة العنصر الحالي بهذه القيم داخل الحلقة.

\n\n
<?php\n$items = ['تفاح', 'موز', 'كرز', 'شمام'];\n$first = reset($items);\n$last = end($items);\n\nforeach ($items as $item) {\n    if ($item === $first) {\n        echo "<strong>الأول: $item</strong><br>";\n    } elseif ($item === $last) {\n        echo "<em>الأخير: $item</em><br>";\n    } else {\n        echo "$item<br>";\n    }\n}\n?>
\n\n

المزايا:

\n
    \n
  • الكود يبدو مضغوطًا و"أنيقًا" للغاية.
  • \n
  • لا حاجة لاستخدام عداد أو دالة count().
  • \n
\n\n

العيوب:

\n
    \n
  • المشكلة الرئيسية: إذا كانت المصفوفة تحتوي على قيم مكررة، فستفشل هذه الطريقة. تخيل أن العنصر الأول والثالث متطابقان. سيعتقد الكود أن العنصر الثالث هو أيضًا الأول.
  • \n
  • reset()

المدونات

توصيات الكتب