5

私は自分のウェブサイト用に PHP の「信号機」スタイルの警告システムを実行しています。これは基本的に、「現在の配列エントリと次の配列エントリの間に X パーセンテージの変化がある場合は、エラーをスローします」と言います。

したがって、foreachループで配列要素をループしていますが、次のようなことができる必要があります:(注:これは基本的な例ですが、アイデアを得るには十分なはずです)

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

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

次の値を取得するために next() タグを配置しましたが、これは配列に対してのみ機能することを理解しています。次の foreach アイテムを取得するために使用できるものは他にありますか?

御時間ありがとうございます!

4

8 に答える 8

10

他の方法でそれを行い、前のエントリを保存してそれらを比較します。

$prev = null;
foreach ($item as $i){
    if ($prev !== null){
        diff($prev, $i);
    }
    $prev = $i
}
于 2011-01-21T15:30:24.017 に答える
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;
    }
}
于 2011-01-21T15:30:05.513 に答える
1

以下を使用できるはずです。

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

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

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

これにより、配列がコピーされ、ポインターが 1 だけ移動します。

于 2011-01-21T15:30:23.580 に答える
1

IMO で最も簡単な解決策は、考え方を変えることです。現在のレコードと次のレコードを検査する代わりに、前のレコードと現在のレコードを検査します。次のものを取得するよりも、前のものを覚えておく方が簡単です。

それが望ましくない場合は、カウンター変数foreachを使用してCスタイルを捨てて反復することもできforます-ただし、注意点が1つあります。PHPのスパース配列はあなたを噛む可能性があるため、array_values()反復する前に検査済みの配列を呼び出すのが最善です。

于 2011-01-21T15:30:24.093 に答える
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 項目シフトするだけです。

于 2011-01-21T15:31:37.417 に答える
1

foreach イテレータではなく、通常の for ループを使用しないのはなぜですか?

<?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;
    }
?>
于 2011-01-21T15:32:21.753 に答える
1

'通常、次の値よりも前の値を使用する方が簡単です。

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

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

    $lastValue = $a['value'];
}
于 2011-01-21T15:32:47.347 に答える
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;
}

実際、必要なものをサポートする配列イテレータ関数があり、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;
        }
于 2011-01-21T15:33:11.130 に答える