2011-01-21 13 views
5

मैं अपनी वेबसाइट के लिए एक PHP 'यातायात प्रकाश' शैली चेतावनी प्रणाली कर रहा हूं, जो मूल रूप से कहता है 'यदि वर्तमान सरणी प्रविष्टि और अगले के बीच एक्स प्रतिशत परिवर्तन है, तो एक त्रुटि फेंक दें'।PHP में अगले foreach आइटम से तत्व खींचें?

तो, मैं अपने सरणी तत्वों के माध्यम से फ़ोरैच लूप में लूपिंग कर रहा हूं, हालांकि इस तरह कुछ करने में सक्षम होना चाहिए: (नोट: यह केवल एक मूल उदाहरण है, लेकिन विचार प्राप्त करने के लिए पर्याप्त होना चाहिए)

foreach($array as $a) 
{ 
$thisValue = $a['value']; 
$nextValue = next($a['value']); 

$percentageDiff = ($nextValue-$thisValue)/$thisValue; 
} 

मैंने अगले() टैग अगले मूल्य प्राप्त करने के लिए रखे हैं लेकिन यह समझते हैं कि यह केवल सरणी के लिए काम करता है। क्या अगली फोरच आइटम प्राप्त करने के लिए मैं कुछ और उपयोग कर सकता हूं?

आपके समय के लिए धन्यवाद!

+0

की [आगे बढ़ें जब पीएचपी 5.2 में एक सरणी पुनरावृत्ति] (http://stackoverflow.com/questions संभव डुप्लिकेट:

यहां एक नमूना है जो सरणी इटरेटर कार्यों का उपयोग कर साहचर्य सरणियों के लिए इस्तेमाल किया जा सकता है/2458099/peek-forward-when-iterating-an-array-in-php-5-2) – Gordon

+0

प्रतिक्रियाओं के लिए धन्यवाद - यह सब करने के वास्तव में महान तरीके की तरह लग रहा था। मैंने @ ऑर्बलिंग और @ कॉन्टैगियस द्वारा प्रदान किए गए समाधान का चयन किया - जबकि यह बहुत ही मामूली ओवरहेड का कारण बनता है, मैं इसके साथ रह सकता हूं कि फ़ंक्शन को कितनी बार बुलाया जाएगा। – Sk446

उत्तर

10

इसे दूसरी तरफ करें, और पिछली प्रविष्टि को स्टोर करें और उनसे तुलना करें।

$prev = null; 
foreach ($item as $i){ 
    if ($prev !== null){ 
     diff($prev, $i); 
    } 
    $prev = $i 
} 
+0

मैंने मतदान किया, यही वह है जो मैं करूंगा। (लेकिन अपने ब्रैकेट की जांच करें!) –

+0

मुझे लगता है कि इस समाधान में अनावश्यक ओवरहेड है;) –

+0

@ ब्रैंडन धन्यवाद, तय – helloandre

4

सरल उत्तर: foreach लूप का उपयोग न करें। बजाय एक साधारण for पाश का उपयोग करें:

for ($i = 0; $i < count($array); $i++) { 
    if (isset($array[$i + 1])) { 
     $thisValue = $array[$i]['value']; 
     $nextValue = $array[$i + 1]['value']; 

     $percentageDiff = ($nextValue-$thisValue)/$thisValue; 
    } 
} 
+1

यह शब्दकोश और हेशटेबल्स जैसे सहयोगी सरणी के लिए काम नहीं करता है, है ना? –

+0

@ ब्रैंडन हां, सही। – lonesomeday

1

आप उपयोग करने के लिए सक्षम होना चाहिए:

foreach($array as $a) 
{ 
    $array_copy = $array; 
    $thisValue = $a['value']; 

    $nextValue = next($array_copy); 
    $nextValue = $nextValue['value']; 

    $percentageDiff = ($nextValue-$thisValue)/$thisValue; 
} 

यह प्रतियां सरणी और फिर साथ द्वारा 1.

1

सबसे आसान समाधान IMO है सूचक ले जाता है अपनी मानसिकता को बदलने के लिए। वर्तमान और अगले रिकॉर्ड का निरीक्षण करने के बजाय, पिछले और वर्तमान रिकॉर्ड का निरीक्षण करें। पिछले एक को याद रखना अगले को प्राप्त करने से आसान है।

आपको लगता है कि नहीं करना चाहते हैं, तो आप भी foreach खाई और for और एक काउंटर चर का उपयोग कर सी-शैली पुनरावृति कर सकते हैं - एक Cavet हालांकि: PHP के विरल सरणियों आप काट सकते हैं, तो आप का निरीक्षण किया सरणी पर सबसे अच्छा कॉल array_values() पुनरावृत्ति से पहले।

1

आप foreach साथ काम करना चाहते हैं, तो आप पिछले मूल्य के साथ के बजाय अगले मूल्य के साथ वर्तमान मूल्य की तुलना कर सकते:

$previous = null; 
foreach ($array as $a) { 
    if (!is_null($previous)) { 
     $thisValue = $previous['value']; 
     $nextValue = $a['value']; 
     $percentageDiff = ($nextValue-$thisValue)/$thisValue; 
    } 
    $previous = $a; 
} 
इस के साथ

तुम सिर्फ पूरे यात्रा बदलाव एक आइटम।

1

फ़ोरैच इटरेटर की बजाय लूप के लिए सामान्य का उपयोग क्यों न करें?

<?php 
    $testArray = array(10,20,30,40,50,60,70,80,90,100); 

    $elementCount = count($testArray); 
    for($loop=0; $loop<$elementCount; $loop++) { 

     $thisValue = $testArray[$loop]; 

     // Check if there *is* a next element. 
     $nextValue = $loop + 1 < $elementCount ? $testArray[$loop + 1] : null; 

     // Calculate the percentage difference if we have a next value. 
     if($nextValue) $percentageDiff = ($nextValue-$thisValue)/$thisValue; 
    } 
?> 
+1

यह शब्दकोश और हेशटेबल्स जैसे सहयोगी सरणी के लिए काम नहीं करता है, है ना? –

+0

@ ब्रैंडन आपको उस उदाहरण में उन लोगों का उपयोग करके array_keys और पुनरावृत्त निकालना होगा। –

+0

@ ब्रैंडन संयोग से, मैं केवल एक संभावित मार्ग को रेखांकित कर रहा था, यह (और वास्तव में सभी अन्य आज तक) स्पष्ट रूप से उपयोग करने योग्य कार्यान्वयन नहीं हैं क्योंकि वे हर बार जब वे पुन: प्रयास करते हैं तो वे 'प्रतिशत भिन्नता' पर खुशी से चिपकते हैं। :-) –

1

'यह आमतौर पर अगले से पिछले मान का उपयोग करना आसान है:

$lastValue = NULL; 
foreach ($array as $a) { 
    if ($lastValue === NULL) { 
     $lastValue = $a['value']; 
     continue; 
    } 

    $percentageDiff = ($a['value'] - $lastValue)/$lastValue; 

    $lastValue = $a['value']; 
} 
+0

पिछला मूल्य काम करेगा - इससे वास्तव में यह बहुत आसान हो जाएगा ... सुनिश्चित नहीं है कि मैंने इसके बारे में क्यों नहीं सोचा :) – Sk446

1
for($i=0;$i<count($array);$i++) { 
$thisValue = $array[$i]; 
$nextValue = $array[i+1]; // will not be set if $i==count($array)-1 
$percentageDiff = ($nextValue-$thisValue)/$thisValue; 
} 

वास्तव में array iterator कार्य करता है जो समर्थन आप क्या जरूरत है, और यह भी बस के साथ एक सरणी thorugh पाशन कर रहे हैं अगला()/prev() आदि ठीक काम करता है लेकिन उपरोक्त समाधान अधिक सुरुचिपूर्ण है

यह foreach के साथ काम नहीं करता है क्योंकि foreach संदर्भों की एक प्रति बनाता है और सरणी पॉइंटर्स को वें सेट नहीं करता है ई सरणी खुद।

$arrayobject = new ArrayObject($array); 
$iterator = $arrayobject->getIterator(); 

     for($i=0;$i<count($array);$i++) { 
      $iterator->seek($i); 
      $thisValue = $iterator->current(); 
      $iterator->seek($i+1); 
      $nextValue = $iterator->current(); 
      $percentageDiff = ($nextValue-$thisValue)/$thisValue; 
     } 
+0

यह शब्दकोश और हैशटेबल्स जैसे सहयोगी सरणी के लिए काम नहीं करता है, है ना? –

+0

यह सही है, इसलिए मैंने सरणी इटरेटर फ़ंक्शंस को लिंक किया जो पूरी तरह उपयुक्त हैं। एक और संभावना अंतिम सरणी तत्व को याद रखना और उस पर आधारित गणना करना और एक प्रविष्टि द्वारा आउटपुट को स्थानांतरित करना है - मैंने उत्तर में एक नमूना कोड जोड़ा –

संबंधित मुद्दे