Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如果存在n个数组元素,如何计算它们的平均值?_Php_Arrays_Loops - Fatal编程技术网

Php 如果存在n个数组元素,如何计算它们的平均值?

Php 如果存在n个数组元素,如何计算它们的平均值?,php,arrays,loops,Php,Arrays,Loops,我有一个月利润数组,我想显示每个月的六个月历史平均值: for each month i: 6monthAvg = round( ( $profits[$i] + (isset($profits[$i-1]) ? $profits[$i-1] : 0) + (isset($profits[$i-2]) ? $profits[$i-2] : 0)

我有一个月利润数组,我想显示每个月的六个月历史平均值:

for each month i:

6monthAvg = round(
                (
                $profits[$i]
                + (isset($profits[$i-1]) ? $profits[$i-1] : 0)
                + (isset($profits[$i-2]) ? $profits[$i-2] : 0)
                + (isset($profits[$i-3]) ? $profits[$i-3] : 0)
                + (isset($profits[$i-4]) ? $profits[$i-4] : 0)
                + (isset($profits[$i-5]) ? $profits[$i-5] : 0)
                ) / 6 
            , 2);
您将看到有效的平均值仅出现在6个月以后,因为它根据
i-5
i
的范围计算平均值

$profits = array(5,7,2,4,7,3,6);
$6moAvg = algorithm($profits);
//Current output =  { 0.83,   2, 2.33,    3, 4.17, 4.67, 4.83}
//Expected output = {    5,   6, 4.67,  4.5,    5, 4.67, 4.83}
或者更具声明性的定义:

if month i has >5 predecessors, sum i and last 5 predecessors, then divide by 6
...
if month i has 5 predecessors, sum i and last 5 predecessors, then divide by 6
if month i has 4 predecessors, sum i and last 4 predecessors, then divide by 5
if month i has 3 predecessors, sum i and last 3 predecessors, then divide by 4
if month i has 2 predecessors, sum i and last 2 predecessors, then divide by 3
if month i has 1 predecessor, sum i and last 1 predecessor, then divide by 2
if month i has no predecessor, sum i, then divide by 1

有没有更简单的方法?我可以将一个计数器保留非零个月,然后除以该计数器,但它会将一行(为可见性添加换行符)变为可能的20行。我知道如何做到这一点,但不知道如何巧妙地使用它,并保持线条/防止丑陋。

这应该适合您:

只需循环您的月份数组,并使用来获取过去6个月(如果存在),然后将它们相加,例如


我真的不认为多行有什么问题。此外,您还可以使用某种扫描线方法,通常会更快:

function algorithm($profits) {
    $n = count($profits);
    $sum = 0;
    $result = array();
    for($i = 0; $i < $n; $i++) {
        $sum += $profits[$i];
        if($i >= 6) {
            $sum -= $profits[$i-6];
        }
        $result[] = round($sum/min(6,$i+1),2);
    }
    return $result;
}

我最后做了下面这样的事情,因为我想它更具可读性:

avg = 1;
for each month i
    if i-1 exists
        avg++;
    if i-2 exists
        avg++;
    ...
    return round(
         (($profits[$i]
         +((isset($profits[$i-1])) ? $profits[$i-1] : 0)
         +((isset($profits[$i-2])) ? $profits[$i-2] : 0)
         ...
         )/avg),2);

我真的不明白为什么多行是个问题。你可以把它们压缩成一行。此外,使用循环通常会使问题不那么容易出错。第二:是否定义了所有利润项目,
isset
只是用作边界检查?或者数组中的某些项可以取消设置吗?
isset
正在检查是否超出范围。数组元素
0
n
具有有效值。
function algorithm($profits) {
    $n = count($profits);
    $sum = 0;
    $result = array();
    for($i = 0; $i < $n; $i++) {
        $sum += $profits[$i];
        if($i >= 6) {
            $sum -= $profits[$i-6];
        }
        $result[] = round($sum/min(6,$i+1),2);
    }
    return $result;
}
function algorithm($profits) {$n = count($profits);$sum = 0;$result = array();for($i = 0; $i < $n; $i++) {$sum += $profits[$i];if($i >= 6) {$sum -= $profits[$i-6];}$result[] = round($sum/min(6,$i+1),2);}return $result;}
$ php -a
Interactive mode enabled

php > function algorithm($profits) {
php {     $n = count($profits);
php {     $sum = 0;
php {     $result = array();
php {     for($i = 0; $i < $n; $i++) {
php {         $sum += $profits[$i];
php {         if($i >= 6) {
php {             $sum -= $profits[$i-6];
php {         }
php {         $result[] = round($sum/min(6,$i+1),2);
php {     }
php {     return $result;
php { }
php > 
php > $profits = array(5,7,2,4,7,3,6);
php > $sixmoAvg = algorithm($profits);
php > var_dump($sixmoAvg);
array(7) {
  [0]=>
  float(5)
  [1]=>
  float(6)
  [2]=>
  float(4.67)
  [3]=>
  float(4.5)
  [4]=>
  float(5)
  [5]=>
  float(4.67)
  [6]=>
  float(4.83)
}
avg = 1;
for each month i
    if i-1 exists
        avg++;
    if i-2 exists
        avg++;
    ...
    return round(
         (($profits[$i]
         +((isset($profits[$i-1])) ? $profits[$i-1] : 0)
         +((isset($profits[$i-2])) ? $profits[$i-2] : 0)
         ...
         )/avg),2);