2011-01-21 6 views
5

Robię system ostrzegawczy w stylu "sygnalizacji świetlnej" dla mojej witryny, który mówi "jeśli jest procentowa zmiana procentowa między bieżącym wpisem w tablicy a następnym, rzuć błąd".Wyciągnij elementy z następnego elementu foreach w PHP?

Tak, przepuszczam przez moje elementy tablicy w pętli foreach, ale muszę mieć możliwość zrobienia czegoś takiego: (uwaga: to tylko podstawowy przykład, ale powinno wystarczyć, aby uzyskać ten pomysł)

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

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

Umieściłem znaczniki next(), aby uzyskać następną wartość, ale rozumiem, że działa tylko w przypadku tablic. Czy jest coś jeszcze, czego mogę użyć, aby uzyskać następny element foreach?

Dziękujemy za poświęcony czas!

+0

możliwe duplikat [Peek przed podczas iteracji tablicę PHP 5.2] (http://stackoverflow.com/questions/2458099/peek-ahead-when-iterating-an-array-in-php-5-2) – Gordon

+0

Dzięki za odpowiedzi - wszystkie wydawały się naprawdę świetnymi sposobami na zrobienie tego. Zdecydowałem się na rozwiązanie dostarczone przez @Orbling i @contagious - choć powoduje to bardzo umiarkowane obciążenie, mogę z tym żyć, biorąc pod uwagę, jak często funkcja będzie wywoływana. – Sk446

Odpowiedz

10

zrobić to w inny sposób, i zapisać poprzedni wpis i porównać je.

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

Głosowałem w górę, to właśnie bym zrobił. (ale sprawdźcie swoje nawiasy!) –

+0

Myślę, że to rozwiązanie ma niepotrzebny narzut;) –

+0

@Bandon dzięki, naprawiono – helloandre

4

Prosta odpowiedź: nie używaj pętli foreach. Użyj prostego for pętlę zamiast:

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

To nie działa dla tablic asocjacyjnych, takich jak słowniki i hashtables, prawda? –

+0

@Bandon Tak, zgadza się. – lonesomeday

1

powinien mieć możliwość korzystania z:

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

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

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

This kopii tablicy, a następnie przesuwa wskaźnik wzdłuż przez 1.

1

Najprostszym rozwiązaniem jest IMO zmienić sposób myślenia. Zamiast sprawdzać bieżący i następny rekord, sprawdź poprzedni i bieżący rekord. Zapamiętywanie poprzedniego jest łatwiejsze niż uzyskanie następnego.

Jeśli użytkownik nie chce, że można również rowu foreach i iteracyjne stylu C stosując for i zmienną przeciw - jeden Cavet jednak: rzadkie tablice PHP może gryźć, więc najlepiej zadzwoń array_values() na kontrolowanego tablicy przed iterowaniem.

1

Jeśli chcesz pracować z foreach, można porównać bieżącą wartość z poprzedniej wartości zamiast z kolejnej wartości:

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

Mając to po prostu przesunąć cały iteracji przez jeden przedmiot.

1

Dlaczego po prostu użyć zwykłej pętli zamiast iteratora foreach?

<?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

To nie działa dla tablic asocjacyjnych, takich jak słowniki i hashtables, prawda? –

+0

@Bandon Musiałbyś wyodrębnić funkcje array_keys i iterować używając tych w tym przykładzie. –

+0

@Brandon Nawiasem mówiąc, tylko wyznaczałem potencjalną trasę, ta (i tak naprawdę wszystkie pozostałe do tej pory) oczywiście nie są użytecznymi implementacjami, ponieważ z przyjemnością przechodzą przez "procentową różnicę" za każdym razem, gdy są iterowane. :-) –

1

„Zwykle łatwiej jest korzystać z poprzednią wartość niż następny:

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

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

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

Poprzednia wartość działałaby - to znacznie ułatwiłoby ... nie wiem, dlaczego o tym nie myślałem :) – 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; 
} 

rzeczywiście istnieje array iterator funkcje, które obsługują co trzeba, a także po prostu przelotowe thorugh tablicy z next()/prev() itp. działa dobrze, ale powyższe rozwiązanie jest bardziej eleganckie niż w przypadku, gdy

Nie działa z foreach, ponieważ foreach tworzy kopię odwołań i nie ustawia wskaźników tablicy w sama tablica.

Oto przykład, który może być stosowany dla tablic asocjacyjnych użyciu funkcji Tablica iteracyjnej:

$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

To nie działa dla tablic asocjacyjnych, takich jak słowniki i hashtables, prawda? –

+0

To jest poprawne, dlatego też połączyłem funkcje iteratora macierzy, które są idealnie dopasowane. inną możliwością jest zapamiętanie ostatniego elementu tablicy i obliczyć na podstawie tego i przesunąć wynik o jeden wpis - dodałem przykładowy kod do odpowiedzi –

Powiązane problemy