Search code examples
phparraysmultidimensional-arraygroupingaverage

Group 2d array data by second level keys and calculate average within each group


I have a two-dimensional array containing names and integer values. The rows do not consistently contain all names. I need to group the data by name and find the average of all values in each group.

Sample array:

$games = [
    [
        "Armstrong_Tony" => 7,
        "Blair_Jarryd" => 7,
        "Broomhead_Tim" => 11
    ],
    [
        "Armstrong_Tony" => 19,
        "Ball_Luke" => 20,
        "Blair_Jarryd" => 20,
        "Broomhead_Tim" => 23
    ],
    [
        "Ball_Luke" => 20,
        "Beams_Dayne" => 14,
        "Blair_Jarryd" => 19,
        "Frost_Jack" => 8,
        "Goldsack_Tyson" => 7
    ]
];

Desired result:

[
  'Armstrong_Tony' => 13,
  'Blair_Jarryd' => 15.333333333333334,
  'Broomhead_Tim' => 17,
  'Ball_Luke' => 20,
  'Beams_Dayne' => 14,
  'Frost_Jack' => 8,
  'Goldsack_Tyson' => 7,
]

My coding attempt:

$arr = array_merge_recursive($games[0],$games[1],$games[2],$games[3],$games[4]);
ksort($arr);

foreach($arr as $player => $val) {

    if(array_key_exists($player, $games[0])) {
        $prev_game_0 = $games[0][$player];
    } else {
        $prev_game_0 = "";
    }
    if(array_key_exists($player, $games[1])) {
        $prev_game_1 = $games[1][$player];
    } else {
        $prev_game_1 = "";
    }
    if(array_key_exists($player, $games[2])) {
        $prev_game_2 = $games[2][$player];
    } else {
        $prev_game_2 = "";
    }
    if(array_key_exists($player, $games[3])) {
        $prev_game_3 = $games[3][$player];
    } else {
        $prev_game_3 = "";
    }
    if(array_key_exists($player, $games[4])) {
        $prev_game_4 = $games[4][$player];
    } else {
        $prev_game_4 = "";
    }

    $last_5_array[$player] = array($prev_game_0, $prev_game_1, $prev_game_2, $prev_game_3, $prev_game_4);
}

Solution

  • This should work for you to get all keys and all averages:

    Here i go through each innerArray and get all key values after saving them in a array i flatter the array and only take unique values

    After that i use array_column() (For PHP +5.5), count() and array_sum() to calculate the average.

    <?php
    
        $arr = array(
                    array(
                        "Armstrong_Tony" => 7,
                        "Blair_Jarryd" => 7,
                        "Broomhead_Tim" => 11
                    ),
                    array(
                        "Armstrong_Tony" => 19,
                        "Ball_Luke" => 20,
                        "Blair_Jarryd" => 20,
                        "Broomhead_Tim" => 23
                    ),
                    array(
                        "Ball_Luke" => 20,
                        "Beams_Dayne" => 14,
                        "Blair_Jarryd" => 19,
                        "Frost_Jack" => 8,
                        "Goldsack_Tyson" => 7
                    )
            );
    
        $keys = array();
        $average = array();
    
        //Get Keys
        foreach($arr as $innerArray)
            $keys[] = array_keys($innerArray);
    
        $keys = array_unique(call_user_func_array('array_merge', $keys));
    
    
        //Get average
        foreach($keys as $key) {
            $values = array_column($arr, $key);
            $average[$key] = array_sum($values) / count($values);
        }
    
        print_r($average);
    
    ?>
    

    Output:

    Array
    (
        [Armstrong_Tony] => 13
        [Blair_Jarryd] => 15.333333333333
        [Broomhead_Tim] => 17
        [Ball_Luke] => 20
        [Beams_Dayne] => 14
        [Frost_Jack] => 8
        [Goldsack_Tyson] => 7
    )