2017-01-23 3 views
0

У меня есть ряд столбцов (Jan, Feb, Mar и т. Д.), И я хочу усреднять значения каждого столбца для каждой строки, сколько бы там ни было.Средние столбцы в PHP

у меня есть:

protected function generateAverage($staff, $type) 
{ 
    $months = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; 
    $staff = array_map(function ($row) use ($type) { 
     if ($row['row_type'] == $type) { 
      return $row; 
     } 
    }, $staff); 

    foreach ($staff as $key => $employee) { 
     $months[0] += $employee['amounts'][0]; 
     $months[1] += $employee['amounts'][1]; 
     $months[2] += $employee['amounts'][2]; 
     $months[3] += $employee['amounts'][3]; 
     $months[4] += $employee['amounts'][4]; 
     $months[5] += $employee['amounts'][5]; 
     $months[6] += $employee['amounts'][6]; 
     $months[7] += $employee['amounts'][7]; 
     $months[8] += $employee['amounts'][8]; 
     $months[9] += $employee['amounts'][9]; 
     $months[10] += $employee['amounts'][10]; 
     $months[11] += $employee['amounts'][11]; 
    } 
    $months = array_map(function ($value) use ($staff) { 
     return $value/(count($staff)/2); 
    }, $months); 
    $months[] = array_sum($months); 
    return $months; 
} 

Вот пример данных, который входит в функции выше:

array:6 [ 
    0 => array:4 [ 
    "amounts" => array:13 [ 
     0 => "30000.00" 
     1 => "30000.00" 
     2 => "30000.00" 
     3 => "30000.00" 
     4 => "30000.00" 
     5 => "30000.00" 
     6 => "30000.00" 
     7 => "30000.00" 
     8 => "30000.00" 
     9 => "30000.00" 
     10 => "30000.00" 
     11 => "30000.00" 
     12 => 360000.0 
    ] 
    "image" => "test.jpg" 
    "row_name" => "Target" 
    "row_type" => "target" 
    ] 
... 

Использование:

$data['aggregates']['Target average'] = $this->generateAverage(array_values($data['staff']), 'target'); 

Я чувствую путь в среднем вычисляется грязно, есть ли лучший способ сделать это?

ответ

1

пара небольших сокращений след

protected function generateAverage($staff, $type) 
{ 
    // create 12 months with 0 value 
    $months = array_fill(0, 12, 0); 
    // use array_filter instead of map 
    $staff = array_filter(function ($row) use ($type) { 
     return $row['row_type'] === $type; 
    }, $staff); 
    // do count outside loop 
    $staffCount = count($staff); 
    // loop employees and add up each month, dividing early 
    foreach ($staff as $employee) { 
     for ($i = 0; $i < 12; $i++) { 
      $months[$i] += $employee['amounts'][$i]/$staffCount; 
     } 
    } 
    return $months; 
} 

Я не знаю, почему вы разделив количество сотрудников на 2 или почему вы суммируются в конце, моя функция просто дает среднее значение в месяц.

0

Поскольку вы используете Laravel, большая часть данных, с которыми вы работаете, это коллекции. Таким образом, перед преобразованием коллекции в массив, вы могли бы использовать avg() helper:

$collection->avg($key); 
+0

он хочет сделать в среднем конкретных данных охватывая несколько записей. Я не думаю, что любая функция avg может волшебным образом выяснить, что он хочет делать. – NDM

+0

@NDM похоже, что он получает данные из БД, в этом случае лучше использовать вспомогательный помощник или коллекцию 'avg()' помощника Query Builder 'помощника(). –

0

Я думаю, вы можете рассмотреть возможность использования array_colum,

1) array_column делает массив всех значений в определенном положении индекса в строке

$column1 = array_column($employee, 0); 
$column2 = array_column($employee, 1); 
$column3 = array_column($employee, 2); 
. 
. 
. 

2) Получить количество столбцов по count($columnX), где Х обозначает индекс столбца

3), используя (1) и (2) вычислить среднее по мере необходимости

Смежные вопросы