Получить дельты из массива с помощью foreach в PHP - PullRequest
2 голосов
/ 16 февраля 2020

Я пытаюсь показать некоторые значения, используя json API. Возвращает дату и некоторое значение плотности в цифрах. Успешно, я напечатал все возвращаемые значения из URL. Теперь я хочу найти разницу между одним значением плотности и значением плотности предыдущего дня.

Я знаю, как рассчитать разницу в нормальных числах c. Но я не уверен, как мне добиться этого внутри foreach l oop.

PHP Код:

$json_url = "https://www.example.com/api";

$json = file_get_contents($json_url);
$obj  = json_decode($json,true);
$data = $obj["data"];

foreach(array_slice($data, 0, 10) as $k) {

    echo $k["date"]." - ".$k["density"]."<br/><br/>";

}

Токовый выход:

14-02-2020 - 110

13-02-2020 - 114

12-02-2020 - 112

11-02-2020 - 110

10-02-2020 - 105

07-02-2020 - 125

06-02-2020 - 122

05-02-2020 - 118

04-02-2020 - 119

03-02-2020 - 119

Ожидаемый выход:

14-02-2020 - 110 - Diff is -4 from Previous Date

13-02-2020 - 114 - Diff is +2 from Previous Date

12-02-2020 - 112 - Diff is +2 from Previous Date

11-02-2020 - 110 - Diff is +5 from Previous Date

10-02-2020 - 105 - Diff is -20 from Previous Date

07-02-2020 - 125 - Diff is +3 from Previous Date

06-02-2020 - 122 - Diff is +4 from Previous Date

05-02-2020 - 118 - Diff is -1 from Previous Date

04-02-2020 - 119 - No Difference - Same

03-02-2020 - 119 - No Difference - Same

Ответы [ 3 ]

1 голос
/ 16 февраля 2020

Просто альтернативная, более короткая версия. Это работает только на прямой for() l oop, работая с текущими и последующими элементами. L oop останавливается на второй от последней, так как последняя всегда будет такой же, как следующая ...

$end = count($array)-1;
for ( $i = 0; $i < $end; $i++ ) {
    if ( $array[$i]["density"] == $array[$i+1]["density"] )    {
        echo "No Difference - Same".PHP_EOL;
    }
    else    {
        echo "Diff is ".($array[$i]["density"]-$array[$i+1]["density"])." from Previous Date".PHP_EOL;
    }

}
echo "No Difference - Same".PHP_EOL;
1 голос
/ 16 февраля 2020

Я бы сделал это за один l oop и использовал бы функцию printf() для форматирования подписанных значений.

Я пишу \n\n вместо вашего <br><br>, чтобы мой демо рендерится правильно.

Мне кажется, что этот фрагмент легко читать и управлять.

Код: ( Демо )

$prev = null;
foreach ($data as $row) {
    if ($prev !== null) {
        $diff = $prev - $row['density'];
        if (!$diff) {
            echo " - No Difference - Same\n\n";
        } else {
            printf(" - Diff is %+d from Next Date\n\n", $diff);
        }
    }
    echo "{$row['date']} - {$row['density']}";
    $prev = $row['density'];
}

Вывод:

14-02-2020 - 110 - Diff is -4 from Next Date

13-02-2020 - 114 - Diff is +2 from Next Date

12-02-2020 - 112 - Diff is +2 from Next Date

11-02-2020 - 110 - Diff is +5 from Next Date

10-02-2020 - 105 - Diff is -20 from Next Date

07-02-2020 - 125 - Diff is +3 from Next Date

06-02-2020 - 122 - Diff is +4 from Next Date

05-02-2020 - 118 - Diff is -1 from Next Date

04-02-2020 - 119 - No Difference - Same

03-02-2020 - 119
1 голос
/ 16 февраля 2020

Для достижения желаемого эффекта вам нужно будет повторять массив по два элемента за раз. Это не может быть легко сделано с foreach напрямую. Поэтому вместо этого я буду реализовывать генератор, который возвращает пары значений из массива за раз.

function getPairs(Array $array) {
    reset($array);
    do {
        $a1  = current($array);
        $key = key($array);
        $a2  = next($array);
        yield [$a1, $a2];
    } while($key = key($array) !== null);
}

Затем вы можете использовать эту реализацию генератора для обхода массива, достигая желаемого эффекта.

$array = [
    ["date" => "14-02-2020", "density" => 110],
    ["date" => "13-02-2020", "density" => 114],
    ["date" => "12-02-2020", "density" => 112],
    ["date" => "11-02-2020", "density" => 110],
    ["date" => "10-02-2020", "density" => 105],
    ["date" => "07-02-2020", "density" => 125],
    ["date" => "12-02-2020", "density" => 112],
    ["date" => "06-02-2020", "density" => 122],
    ["date" => "05-02-2020", "density" => 118],
    ["date" => "04-02-2020", "density" => 119],
    ["date" => "03-02-2020", "density" => 119],
];

foreach(getPairs($array) as [$a, $b]) {
    // We must check if $b is empty to account for end of the array
    if ($b) {
        $diff = $a["density"] - $b["density"];
    } else { // Otherwise there are no more elements to diff against
        $diff = 0;
    }
    if ($diff > 0) {
        $diff = "+$diff";
    }
    echo "{$a['date']} - {$a['density']} - Diff is $diff from Previous Date<br><br>";
}

Это должно дать вам желаемый результат.

14-02-2020 - 110 - Diff is -4 from Previous Date

13-02-2020 - 114 - Diff is +2 from Previous Date

12-02-2020 - 112 - Diff is +2 from Previous Date

11-02-2020 - 110 - Diff is +5 from Previous Date

10-02-2020 - 105 - Diff is -20 from Previous Date

07-02-2020 - 125 - Diff is +13 from Previous Date

12-02-2020 - 112 - Diff is -10 from Previous Date

06-02-2020 - 122 - Diff is +4 from Previous Date

05-02-2020 - 118 - Diff is -1 from Previous Date

04-02-2020 - 119 - Diff is 0 from Previous Date

03-02-2020 - 119 - Diff is 0 from Previous Date

NB

Технически говоря, вы фактически не получаете разницу между текущей датой и предыдущей датой, Вот. Скорее, вы получаете разницу между текущей датой и следующей датой. Если вы получали дельты между предыдущими датами, вам вообще не понадобилась бы информация со следующей даты. Вместо этого вы бы просто использовали временную переменную для хранения последнего значения density и сравнивали его с каждой итерацией. Тем не менее, я адаптировал свой ответ к ожидаемому результату.

В противном случае ожидаемый результат будет на самом деле:

14-02-2020 - 110 - Diff is +110 from Previous Date

13-02-2020 - 114 - Diff is +4 from Previous Date

12-02-2020 - 112 - Diff is -2 from Previous Date

11-02-2020 - 110 - Diff is -2 from Previous Date

10-02-2020 - 105 - Diff is -5 from Previous Date

07-02-2020 - 125 - Diff is +20 from Previous Date

12-02-2020 - 112 - Diff is -13 from Previous Date

06-02-2020 - 122 - Diff is +10 from Previous Date

05-02-2020 - 118 - Diff is -4 from Previous Date

04-02-2020 - 119 - Diff is +1 from Previous Date

03-02-2020 - 119 - Diff is 0 from Previous Date

И для достижения этого вам не нужно Генератор реализации я использовал вообще. Вы можете просто сделать это с помощью обычного foreach l oop, например, так:

$lastDiff = 0; // Initialize the diff to 0

foreach($array as $a) {
    $date = $a['date'];
    $density = $a['density'];
    $diff = $a["density"] - $lastDiff; // diff against the last known value
    if ($diff > 0) {
        $diff = "+$diff";
    }
    echo "$date - $density - Diff is $diff from Previous Date<br><br>";
    $lastDiff = $a["density"]; // store the last known density here for the next iteration
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...