PHP

2010-03-16 5 views
28

में किसी सरणी को पुन: सक्रिय करते समय आगे बढ़ें क्या PHP 5.2 में सरणी को पुनरारंभ करते समय "आगे बढ़ना" संभव है? उदाहरण के लिए, मैं अक्सर foreach का उपयोग एक सरणी से डेटा हेरफेर करने के लिए:PHP

foreach($array as $object) { 
    // do something 
} 

लेकिन मैं अक्सर सरणी के माध्यम से जा जबकि अगले तत्व पर नज़र की जरूरत है। मुझे पता है कि मैं for लूप का उपयोग कर सकता हूं और इसके आइटम को इसके सूचकांक ($array[$i+1]) द्वारा संदर्भित कर सकता हूं, लेकिन यह सहयोगी सरणी के लिए काम नहीं करेगा। क्या मेरी समस्या के लिए कोई शानदार समाधान है, शायद एसपीएल शामिल है?

उत्तर

48

आप इस उद्देश्य के लिए CachingIterator उपयोग कर सकते हैं:

तो तुम कुछ इस तरह कर सकता है। ,

var_dump($collection->current()); // null 
var_dump($collection->getInnerIterator()->current()); // Cat 

इस प्रकार जब आप foreach$collection से अधिक, भीतरी ArrayIterator की वर्तमान तत्व कार्य करें:

$collection = new CachingIterator(
        new ArrayIterator(
         array('Cat', 'Dog', 'Elephant', 'Tiger', 'Shark'))); 

CachingIterator हमेशा भीतरी इटरेटर के पीछे एक कदम है:

यहाँ एक उदाहरण है पहले से ही तत्व होगा, जिससे आप इसमें देख सकेंगे:

foreach($collection as $animal) { 
    echo "Current: $animal"; 
    if($collection->hasNext()) { 
     echo " - Next:" . $collection->getInnerIterator()->current(); 
    } 
    echo PHP_EOL; 
} 

विल उत्पादन:

Current: Cat - Next:Dog 
Current: Dog - Next:Elephant 
Current: Elephant - Next:Tiger 
Current: Tiger - Next:Shark 
Current: Shark 

किसी कारण मैं व्याख्या नहीं कर सकते के लिए, CachingIterator हमेशा स्ट्रिंग के लिए वर्तमान तत्व परिवर्तित करने के लिए कोशिश करेंगे। यदि आप किसी ऑब्जेक्ट संग्रह पर पुन: प्रयास करना चाहते हैं और गुणों को किसी विधियों तक पहुंचने की आवश्यकता है, तो निर्माता को दूसरे पैरा के रूप में CachingIterator::TOSTRING_USE_CURRENT पास करें।


एक sidenote पर, CachingIterator परिणाम ही सब यह अब तक अधिक दोहराया गया है कैश करने के लिए क्षमता से नाम है हो जाता है। इसके लिए काम करने के लिए, आपको CachingIterator::FULL_CACHE के साथ इसे तुरंत चालू करना होगा और फिर आप कैश किए गए परिणामों को getCache() के साथ ला सकते हैं।

+1

+1 इन्हें भी नहीं पता था ([x] Iterators) बहुत उपयोगी, निर्देशिकाइटरेटर espec।अगली बार जब मैं फाइल सामान कर रहा हूं तो यह मुझे काम का एक बड़ा भार बचाने जा रहा है। धन्यवाद :) – Psytronic

+2

@Psytronic वे वास्तव में साफ हैं। उन्हें ढेर करने की क्षमता बहुत अच्छी और लचीली सामग्री के लिए अनुमति देता है। दुर्भाग्यवश, खराब दस्तावेज हैं, लेकिन http://www.phpro.org/tutorials/Introduction-to-SPL.html – Gordon

+0

दुर्भाग्य से, यदि सरणी में ऑब्जेक्ट्स हैं और तार नहीं हैं तो समाधान काम नहीं करता है। मुझे निम्नलिखित अपवाद मिलते हैं: 'कैच करने योग्य घातक त्रुटि: कक्षा MySampleClass का ऑब्जेक्ट लाइन 3 9 8' – pako

6

आप next और prev का उपयोग किसी सरणी को फिर से करने के लिए कर सकते हैं। current वर्तमान आइटम मान और key वर्तमान कुंजी देता है।

while (key($array) !== null) { 
    next($array); 
    if (key($array) === null) { 
     // end of array 
    } else { 
     $nextItem = value($array); 
    } 
    prev($array); 

    // … 

    next($array); 
} 
+2

कोड बहुत जटिल लग रहा है, और यह त्रुटि के लिए प्रवण है (बहुत सारे "nexts/prevs" और बहुत अजीब चीजें हो सकती हैं ...)। – pako

17

array_keys का उपयोग करें।

$keys = array_keys($array); 
for ($i = 0; $i < count($keys); $i++) { 
    $cur = $array[$keys[$i]]; 
    $next = $array[$keys[$i+1]]; 
} 
+0

मैं इस तरह की बुनियादी बात करने के लिए स्वीकृत उत्तर की सभी जटिलताओं पर क्यों विचार करूंगा, जब मूल कार्यों में उत्तर सही होगा? धन्यवाद। – Noumenon

+0

मुझे यह उत्तर पसंद है, वस्तुओं को संख्यात्मक रूप से संदर्भित करने में सक्षम होने के कई फायदे हैं। –

3

मुझे पता है कि यह एक पुरानी पोस्ट है, लेकिन मैं अब वर्तमान/अगली/पिछली चीज़ को बेहतर समझा सकता हूं। उदाहरण:

$array = array(1,2,3,2,5); 

foreach($array as $k => $v) { 
    // in foreach when looping the key() and current() 
    // is already pointing to the next record 
    // And now we can print current 
    print 'current key: '.$k.' and value: '.$v; 
    // if we have next we can print its information too (key+value) 
    if(current($array)) { 
     print ' - next key: '.key($array).' and value: '.current($array); 
     // at the end we must move pointer to next 
     next($array); 
    } 
    print '<br>'; 
} 

// prints: 
// current key: 0 and value: 1 - next key: 1 and value: 2 
// current key: 1 and value: 2 - next key: 2 and value: 3 
// current key: 2 and value: 3 - next key: 3 and value: 2 
// current key: 3 and value: 2 - next key: 4 and value: 5 
// current key: 4 and value: 5 
+0

मुझे लगता है कि अगर $ सरणी में गलत मूल्य है तो यह ठीक से रिपोर्ट नहीं करेगा। – grantwparks

0

I know I could use a for loop and reference the next item by its index ($array[$i+1]), but it wouldn't work for associative arrays.

एक क्रमिक रूप से में अपने साहचर्य सरणी परिवर्तित करने पर विचार करें array_values() के साथ एक अनुक्रमित, आप पाश समाधान के लिए सरल उपयोग करने के लिए अनुमति देता है।