2

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;
Rao
  • 20,781
  • 11
  • 57
  • 77
codeLover
  • 69
  • 7
  • this line is wrong `echo ''.$row->label.'';` ~ it will add a closing `tr` tag for every iteration through the loop and will throw any formatting out of alignment – Professor Abronsius Jan 28 '16 at 09:21
  • The `print_r` output you provide has been manually manipulated and could not have come from `print_r`. Please make sure to provide the array as you have it, otherwise the solution will not be what you need. – trincot Jan 28 '16 at 09:27
  • You use `->` notation, but your data shows no objects, only arrays. Could you provide the error messages you get? – trincot Jan 28 '16 at 09:36
  • I have convert object to array $arr = array(); $arr = objToArray($rows, $arr); $finalArr = array(); foreach($arr as $newArr){ $i=1; foreach($newArr['value'] as $valueArr){ $temp = array(); $name = $valueArr['firstname'].' '.$valueArr['lastname']; $temp[$name]['count_'.$i] = $valueArr['count']; echo $name; print_r($finalArr); if(multiKeyExists($finalArr,$name)){ $temp[$name]['count_'.$i] = $valueArr['count']; } $i++; array_push($finalArr,$temp); } } but still it not working for me – codeLover Jan 28 '16 at 10:25
  • What is not working, what error message you get, what output is wrong? Can you be more specific? Please add this information in the question, because in comments it is almost unreadable. – trincot Jan 28 '16 at 10:32
  • Where do you get your data from? From a database query? If that is the case, please provide the query, because it is **much** more efficient to make the query output what you want then to manipulate the query's output in PHP. – trincot Jan 28 '16 at 10:37

2 Answers2

0

Just initialize $final array outside of first loop. like below..

    $final = [];

    foreach($rows as $row)
    {
        echo '<th>'.$row->label.'</th></tr>';
        $i = 1;    
        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;
Amit Rajput
  • 2,061
  • 1
  • 9
  • 27
0

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

trincot
  • 317,000
  • 35
  • 244
  • 286
  • Thanks for the solution :) But I need red,yellow as column name and firstname under names like Name red yellow green white abc 8 2 4 0 dim 2 8 0 0 sys 1 0 8 45 xyz 7 2 0 5 – codeLover Jan 28 '16 at 11:23
  • OK, adapted answer to have rows/columns switched to what I had presented before. – trincot Jan 28 '16 at 11:46