Search code examples
phparraysmultidimensional-arrayforeacharray-push

Foreach overwrites previous records in multidimensional array


I have a multidimensional array, and I want to show this array in tabular form like

+------+-----+--------+-------+-------+
| Name | red | yellow | green | white |
+------+-----+--------+-------+-------+
| abc  |   8 |      2 |     4 |     0 |
| xyz  |   2 |      8 |     0 |     0 |
+------+-----+--------+-------+-------+

The following is the array that I've

[0] => array(
        'label'=> 'red',
        [value] => Array
        (
                [0] => array
                (
                        [count] => 47
                        [firstname] => Syst

                )
                [1] => array
                (
                        [count] => 2
                        [firstname] => xyz
                )

                [2] => array
                (
                        [count] => 8
                        [firstname] => abc
                )
)
[1] => array(
        'label'=> 'yellow',
        [value] => Array
        (
                [0] => array
                (
                        [count] => 4
                        [firstname] => dim
                )
                [1] => array
                (
                        [count] => 2
                        [firstname] => abc
                )
                [2] => array
                (
                        [count] => 8
                        [firstname] => xyz
                )
        )

and so on I have tired below code but I don't know whats the problem with code.

foreach($rows as $row)
{
    echo '<th>'.$row->label.'</th></tr>';
    $i = 1;
    $final = [];
    foreach($row->value as $v){
        $temp = [];
        $temp[$v->firstname.' '.$v->lastname] = [];
        $output = findKey($final, $v->firstname.' '.$v->lastname);
        if($output){
            $temp[$v->firstname.' '.$v->lastname]['count'] = $v->count ;
            $temp[$v->firstname.' '.$v->lastname][$row->label.'_'.$row->color] =  $v->count ;
        }
        array_push($final,$temp);
    }
}
print_r($rows); //die;

Solution

  • The print_r output you have provided is not consistent -- it has been manipulated to add the label keys. print_r would have output them as [label], not as "label", also, print_r would not have output a comma at the end of the same line.

    So, with the risk that the solution will not work, because you have not provided a correct array, I provide here a solution based on the following array:

    $finalArr = 
    array(
        array(
            'label' => 'red',
            'value' => Array (
                    array ("count" => 47, "firstname" => 'Syst'),
                    array ("count" => 2, "firstname" => 'xyz'),
                    array ("count" => 8, "firstname" => 'abc')
            )
        ),
        array(
            'label' => 'yellow',
            "value" => Array (
                    array ("count" => 4, "firstname" => 'dim'),
                    array ("count" => 2, "firstname" => 'abc'),
                    array ("count" => 8, "firstname" => 'xyz')
            )
        )
    );
    

    Then the solution could be this:

    // collect unique list of "firstname" values
    $rowHeaders = array();
    foreach($finalArr as $column) {
        $rowHeaders = array_merge($rowHeaders, array_column($column["value"], "firstname"));
    }
    $rowHeaders = array_unique($rowHeaders);
    usort($rowHeaders, 'strcasecmp');
    
    // get column headers
    $colHeaders = array_column($finalArr, "label");
    
    // create matrix: first column
    $matrix = array(array_merge(array("Name"), $colHeaders));
    foreach($rowHeaders as $firstname) {
        $matrix[] = array($firstname);
    }
    // ... and colour columns:
    foreach($finalArr as $colIndex => $column) {
        $names = array_column($column["value"], "firstname");
        foreach ($rowHeaders as $rowIndex => $name) {
            $matrix[$rowIndex+1][] = in_array($name, $names) ? $column["value"][array_search($name, $names)]["count"] : 0;
        }
    }
    
    // convert matrix into HTML table
    $html = "";
    $td = "th";
    foreach ($matrix as $row) {
        $html .= "<tr><$td>" . implode("</$td><$td>", $row) . "</$td></tr>\n"; 
        $td = "td";
    }
    $html = "<table border=1>\n$html</table>";
    
    // output html:
    echo $html;
    

    The output is:

    <table border=1>
    <tr><th>Name</th><th>red</th><th>yellow</th></tr>
    <tr><td>abc</td><td>8</td><td>2</td></tr>
    <tr><td>dim</td><td>0</td><td>4</td></tr>
    <tr><td>Syst</td><td>47</td><td>0</td></tr>
    <tr><td>xyz</td><td>2</td><td>8</td></tr>
    </table>
    

    Which in a browser renders as:

    table output