Извлечь элементы из следующего элемента foreach в PHP? - PullRequest
5 голосов
/ 21 января 2011

Я делаю систему предупреждений в стиле PHP «светофор» для своего веб-сайта, которая в основном говорит: «Если есть процентное изменение X между текущей записью массива и следующей, выведите ошибку».

Итак, я перебираю элементы массива в цикле foreach, однако нужно иметь возможность сделать что-то вроде этого: (примечание: это только базовый пример, но должно быть достаточно, чтобы понять идею)

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

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

Я добавил теги next (), чтобы получить следующее значение, но понимаю, что это работает только для массивов. Есть ли что-то еще, что я могу использовать, чтобы получить следующий элемент foreach?

Спасибо за ваше время!

Ответы [ 8 ]

10 голосов
/ 21 января 2011

сделайте это по-другому, сохраните предыдущую запись и сравните их.

$prev = null;
foreach ($item as $i){
    if ($prev !== null){
        diff($prev, $i);
    }
    $prev = $i
}
4 голосов
/ 21 января 2011

Простой ответ: не используйте цикл 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 голос
/ 21 января 2011
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;
}

Действительно, итератор массива функции, которые поддерживают то, что вам нужно, а также просто зацикливание массива с помощью next () / 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;
        }
1 голос
/ 21 января 2011

'Предыдущее значение обычно проще использовать, чем следующее:

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

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

    $lastValue = $a['value'];
}
1 голос
/ 21 января 2011

Почему бы не использовать обычный цикл for вместо итератора 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 голос
/ 21 января 2011

Если вы хотите работать с foreach, вы можете сравнить текущее значение с предыдущим значением вместо следующего значения:

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

С этим вы просто сдвигаетевся итерация по одному элементу.

1 голос
/ 21 января 2011

Самое простое решение IMO - изменить свое мышление. Вместо проверки текущей и следующей записи, проверьте предыдущую и текущую запись. Помнить предыдущий легче, чем получить следующий.

Если вы не хотите этого, вы также можете отказаться от foreach и выполнить итерацию в стиле C, используя for и переменную счетчика - хотя один каветт: разреженные массивы PHP могут вас укусить, поэтому лучше всего позвонить array_values() в проверяемом массиве перед итерацией.

1 голос
/ 21 января 2011

Вы должны быть в состоянии использовать:

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

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

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

Это копирует массив и затем перемещает указатель на 1.

...