计算PHP

时间:2018-02-27 23:13:06

标签: php arrays xml range moving-average

我试图计算PHP中一系列XML元素的平均值,但还没有找到任何解决方案。

以下是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将返回&#34;关闭&#34;的平均值。 2018-02-26和2018-02-23 =(1586,96 + 1577,11)/ 2。

2018-02-23的平均值将返回(1577,11 + 1565,5)/ 2.

正如您所看到的,我试图将每个元素的累计总和相加,但出于某种原因,我无法理解它不会起作用。

如何计算元素的移动平均值?

1 个答案:

答案 0 :(得分: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++;
}

Demo

结果

  

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;

,则会获得与之前相同的结果

Demo