arrays — вычисляет среднее значение диапазона элементов XML в переполнении стека

Я пытаюсь вычислить среднее значение диапазона элементов XML в PHP, но пока не нашел решения.

Вот элементы XML.

<root>
<quoteDay>
<date>2018-02-26</date>
<close>1586,96</close>
</quoteDay>
<quoteDay>
<date>2018-02-23</date>
<close>1577,11</close>
</quoteDay>
<quoteDay>
<date>2018-02-22</date>
<close>1565,5</close>
</quoteDay>
</root>

Вот код PHP:

<?php
$xml = simplexml_load_file("file.xml") or die("Error: Cannot create object");
$id = -1;
$total[] = 0;

foreach ($xml->root as $root) {
foreach ($root->quoteDay as $quoteDay) {
$id ++;
$total[] += $root->quoteDay[$id]->close;
$close = number_format(round($quoteDay->close,0));
echo $quoteDay->date; echo $close; echo $total[$id+1];
}
}
?>

Итак, для каждой цитаты день я хотел бы вернуть дату, закрытие и скользящее среднее.

Дата 2018-02-26 будет возвращать среднее значение «закрытия» для 2018-02-26 и 2018-02-23 = (1586,96 + 1577,11) / 2.

Среднее значение за 2018-02-23 вернется (1577,11 + 1565,5) / 2.

Я, как вы можете видеть, пытался суммировать совокупную общую сумму для каждого элемента, но по какой-то причине я не могу понять, что это не сработает.

Как я могу выполнить вычисление скользящего среднего для элементов?

1

Решение

Для достижения вашего результата вам нужно сделать пару вещей:

  • simplexml_load_file() уже дает вам рут, так что вам не нужен ваш первый цикл
  • $total массив не нужен
  • Ваш XML имеет , как десятичные разделители, но PHP использует .так что вам нужно заменить их, чтобы сделать математику и не потерять десятичные дроби (здесь я приведу float который может заставить вас потерять точность, посмотрите на bcmath чтобы избежать этого)
  • Я предполагаю, что для первого дня, когда нет предыдущего, скользящая средняя является значением дня

Итак, ваш код будет выглядеть так:

<?php
$xml = simplexml_load_file("a.xml") or die("Error: Cannot create object");
$id = 0;
foreach ($xml->quoteDay as $quoteDay) {
echo "Moving average for ".$quoteDay->date.":".PHP_EOL;
$current = (float) str_replace(",", ".", $quoteDay->close);
$previous = $xml->quoteDay[$id + 1]
? (float) str_replace(",", ".", $xml->quoteDay[$id + 1]->close)
: $current;
$movingMean = ($current + $previous) / 2;
echo $movingMean.PHP_EOL;
echo PHP_EOL;
$id++;
}

демонстрация

Результат

Скользящая средняя за 2018-02-26:
1582.035

Скользящая средняя за 2018-02-23:
1571.305

Скользящая средняя за 2018-02-22:
1565,5

Чтобы обобщить это $daysInMovingMean дни, используйте for цикл, чтобы получить дни до необходимых дней, останавливаясь раньше, если это необходимо (то есть больше не осталось дней):

$xml = simplexml_load_file("a.xml") or die("Error: Cannot create object");
$id = 0;
$daysInMovingMean = 3;
foreach ($xml->quoteDay as $quoteDay) {
echo "Moving average for ".$quoteDay->date.":".PHP_EOL;
$sum = 0;
for ($days = 0; $days < $daysInMovingMean; $days++) {
if (!$xml->quoteDay[$id + $days]) break;
$sum += (float) str_replace(",", ".", $xml->quoteDay[$id + $days]->close);
}
$sumovingMean = $sum / $days;
echo $sumovingMean.PHP_EOL;
echo PHP_EOL;
$id++;
}

Обратите внимание, что в этом примере вы получите те же результаты, что и раньше, если вы установите $daysInMovingMean = 2;

демонстрация

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]