सवाल "foreach का पहला और आखिरी पुनरावृत्ति" Stack Overflow पर क्यों धमाल मचाता है?
\n\nयदि आपने कभी PHP में लिखा है और सूची के पहले तत्व में CSS क्लास जोड़ने की कोशिश की है या प्रत्येक तत्व के बाद एक विभाजक डालने की कोशिश की है, आखिरी को छोड़कर, तो आप पहले ही इस समस्या का सामना कर चुके हैं। Stack Overflow पर इस प्रश्न को 150,000 से अधिक बार देखा गया है और सैकड़ों टिप्पणियाँ हैं। क्यों? क्योंकि foreach एक शक्तिशाली लेकिन "अंधा" लूप है: यह नहीं जानता कि यह किस चरण में है।
\n\nइस लेख में, हम PHP 8.x पर 4 कार्यशील दृष्टिकोणों का विश्लेषण करेंगे, सरल से लेकर पेशेवर तक। आप सीखेंगे कि "गंदे" हैक से कैसे बचें और ऐसा कोड लिखें जिसे कोड रिव्यू में दिखाने में शर्म न आए।
\n\n\n\nसमस्या: foreach अपना नंबर क्यों नहीं जानता?
\n\nfor के विपरीत, जहाँ आपके पास काउंटर $i होता है, foreach ऐरे के आंतरिक पॉइंटर के साथ काम करता है। यह सरल पुनरावृत्ति के लिए आदर्श है, लेकिन जब "केवल पहले" या "केवल आखिरी" तत्व के लिए कोई कार्रवाई करने की आवश्यकता होती है, तो मुश्किलें शुरू हो जाती हैं।
एक सामान्य कार्य का उदाहरण:
\n// आइटम की सूची को अल्पविराम से अलग करके प्रदर्शित करें, लेकिन आखिरी के बाद कोई अल्पविराम नहीं\n$items = ['दूध', 'ब्रेड', 'अंडे', 'पनीर'];\n\nforeach ($items as $item) {\n echo $item . ', '; // ओह, आखिरी अल्पविराम अनावश्यक है!\n}\n\n\nआउटपुट: दूध, ब्रेड, अंडे, पनीर, — यह सुंदर नहीं है। चलिए इसे ठीक करते हैं।
विधि 1: काउंटर + count() — क्लासिक तरीका
\n\nसबसे स्पष्ट तरीका एक काउंटर वेरिएबल बनाना और इसे तत्वों की कुल संख्या से तुलना करना है।
\n\n$items = ['दूध', 'ब्रेड', 'अंडे', 'पनीर'];\n$total = count($items);\n$i = 1;\n\nforeach ($items as $item) {\n if ($i === 1) {\n echo "<strong>पहला: $item</strong><br>";\n } elseif ($i === $total) {\n echo "<em>आखिरी: $item</em><br>";\n } else {\n echo "$item<br>";\n }\n $i++;\n}\n\n\nलाभ:
\n- \n
- सरलता और पठनीयता। \n
- किसी भी ऐरे के साथ काम करता है, जिसमें एसोसिएटिव ऐरे भी शामिल हैं। \n
नुकसान:
\n- \n
count()और काउंटर के आरंभीकरण को याद रखना होगा। \n- यदि ऐरे खाली है,
$total = 0, और पहला पुनरावृत्ति कभी नहीं होगा — जाँच करनी होगी। \n Iteratorऑब्जेक्ट (जैसे जनरेटर) के लिए उपयुक्त नहीं है। \n
विधि 2: फ्लैग और reset() / end() — काउंटर के बिना सुंदरता
\n\nपुनरावृत्तियों को गिनने के बजाय, लूप शुरू होने से पहले ऐरे के पहले और आखिरी तत्वों को याद किया जा सकता है।
\n\n$items = ['दूध', 'ब्रेड', 'अंडे', 'पनीर'];\n\n$first = reset($items); // 'दूध'\n$last = end($items); // 'पनीर'\nreset($items); // पॉइंटर को शुरुआत में वापस लाएँ!\n\nforeach ($items as $key => $item) {\n if ($item === $first) {\n echo "पहला: $item\\n";\n } elseif ($item === $last) {\n echo "आखिरी: $item\\n";\n } else {\n echo "$item\\n";\n }\n}\n\n\nमहत्वपूर्ण! reset() और end() फ़ंक्शन ऐरे के आंतरिक पॉइंटर को बदलते हैं। end() के बाद, reset() को कॉल करना अनिवार्य है, अन्यथा foreach शुरुआत से शुरू नहीं होगा।
लाभ:
\n- \n
- काउंटर की आवश्यकता नहीं है। \n
- एसोसिएटिव ऐरे के साथ काम करता है। \n
नुकसान:
\n- \n
- खतरा: यदि ऐरे में डुप्लिकेट मान हैं (जैसे, दो "पनीर"), तो आखिरी तत्व गलत तरीके से पहचाना जाएगा। \n
Iteratorऑब्जेक्ट के लिए उपयुक्त नहीं है। \n- पॉइंटर को मैन्युअल रूप से रीसेट करना आवश्यक है। \n
विधि 3: array_keys() — एसोसिएटिव ऐरे और ऑब्जेक्ट के लिए
\n\nयदि आपको कुंजियों (न केवल मानों) या Iterator ऑब्जेक्ट के साथ काम करने की आवश्यकता है, तो आप सभी कुंजियों की सूची प्राप्त कर सकते हैं और इंडेक्स की जाँच कर सकते हैं।
$items = ['a' => 'दू