Hello.

There is an array of this type:

array(4) { array(4) {["name"]=> "name_one" , ["y"]=> "2016", ["q"]=> "2", ["st"]=> "1"} array(4) {["name"]=> "name_one" , ["y"]=> "2017", ["q"]=> "3", ["st"]=> "2"} array(4) {["name"]=> "name_two" , ["y"]=> "2017", ["q"]=> "1", ["st"]=> "1"} array(4) {["name"]=> "name_two" , ["y"]=> "2017", ["q"]=> "2", ["st"]=> "2"} } 

It is necessary to form and fill a table based on the data from this array.

table

With the output header and the formation of the table itself handled, but how to fill the cells, I can not think of.

  • Yana, you would format the array, there is a button код - vp_arth
  • 2
    Rearrange the structure to [name_one => [2016 => [q1 => null, q2 => 1, ..], ..], ..] before rendering - vp_arth

2 answers 2

To begin with, we will regroup the data taking into account dependencies.
At the same time, let's save the names / years / qs sets for building the header.

 $rows = [ ['name' => 'name_one', 'y' => '2016', 'q' => '2', 'st' => 1], ['name' => 'name_one', 'y' => '2017', 'q' => '3', 'st' => 2], ['name' => 'name_two', 'y' => '2017', 'q' => '1', 'st' => 1], ['name' => 'name_two', 'y' => '2017', 'q' => '2', 'st' => 2], ]; $data = []; $names = []; $years = []; $qs = []; foreach ($rows as $row) { $link = &$data; foreach (['name', 'y'] as $field) { if (!isset($link[$row[$field]])) $link[$row[$field]] = []; $link = &$link[$row[$field]]; } $link[$row['q']] = $row['st']; unset($link); // $names[$row['name']] = true; $years[$row['y']] = true; $qs[$row['q']] = true; } // Опционально сортируем $names = array_keys($names); sort($names); $years = array_keys($years); sort($years); $qs = array_keys($qs); sort($qs); 

The structure is there, the matter is small - to render the table: In the header there are 2 lines, in the first years there is a corresponding colspan .
Next, display the data itself.
foreach($years as $y => $_) can be used to iterate over the keys, however, we have already extracted the keys using array_keys .

Feeddle

 ?> <table border="1"> <tr> <th>Name <?foreach($years as $y):?> <th colspan="<?=count($qs)?>"><?=$y?> <?endforeach?> <tr> <th>&nbsp; <?foreach($years as $y):?> <?foreach($qs as $q):?> <th>q<?=$q?> <?endforeach?> <?endforeach?> <?foreach($names as $name):?> <tr> <td><?=$name?> <?foreach($years as $y):?> <?foreach($qs as $q):?> <td><?=isset($data[$name][$y][$q]) ? $data[$name][$y][$q] : '' ?> <?endforeach?> <?endforeach?> <?endforeach?> </table> 

The result will look something like this:

 <table border=1> <tr> <th>Name <th colspan="3">2016 <th colspan="3">2017 <tr> <th>&nbsp; <th>q1 <th>q2 <th>q3 <th>q1 <th>q2 <th>q3 <tr> <td>name_one <td></td> <td>1</td> <td></td> <td></td> <td></td> <td>2</td> <tr> <td>name_two <td></td> <td></td> <td></td> <td>1</td> <td>2</td> <td></td> </table> 

    Try using the printf () function . For example, in a loop, you can loop through an array or data from a database and output the necessary one as table rows.

     printf(" <tr class='%s'> <td>%s</td> <td>%s</td> <td>%s</td> </tr> ", $a, $b, $c, $d ); 

    Instead of the %s placeholder, values ​​from variables will be inserted. Order matters.

    For convenience, you can assemble a different array of what you have.

    • one
      Again your print_f tulish. Stop it, it's indecent. - vp_arth
    • @vp_arth And you are all buzish)) I would answer the question then - n.osennij
    • I'm lazy, I gave the idea in the comments) - vp_arth
    • @vp_arth yes, grouping will simplify the output. But how a person derives - not a word at all. More precisely, apparently, the person displayed an empty table, but did not fill in the data. - n.osennij