0

I have the following array which came up from my two days work with arrays.

Array (
      [0]=> Array(
            [6]=>Array(
                  [English] => 17
                  [Maths] => 11
                  [Science] => 15
                  )
              )
      [1] =>Array(
            [7]=>Array(
                  [English] => 13
                  [Maths] => 15
                  [Science] => 11
                  )
             )
      [2] =>Array(
            [8]=>Array(
                  [English] => 9
                  [Maths] => 17
                  [Science] => 9
                  )
             )
     )

Here array key 6,7, and 8 are unique. I want to print out this array in this format.

<table border="1">
  <thead>
    <tr>
      <th>Roll No</th>
      <th>English</th>
      <th>Maths</th>
      <th>Science</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>6</td>
      <td>17</td>
      <td>11</td>
      <td>15</td>
    </tr>
    <tr>
      <td>7</td>
      <td>13</td>
      <td>15</td>
      <td>11</td>
    </tr>
    <tr>
      <td>8</td>
      <td>9</td>
      <td>17</td>
      <td>9</td>
    </tr>
  </tbody>
  </table>

Note: the header and the rows are dynamic.

2
  • 2
    I think you have made a complex array . Commented Feb 27, 2016 at 9:25
  • run foreach inside of foreach Commented Feb 27, 2016 at 9:26

3 Answers 3

1

Given this array structure (taken from your question, put into code):

$rows = array(
    array(
        6 => array(
            'English' => 17,
            'Maths' => 11,
            'Science' => 15
        )
    ),
    array(
        7 => array(
            'English' => 13,
            'Maths' => 15,
            'Science' => 11
        )
    ),
    array(
        8 => array(
            'English' => 9,
            'Maths' => 17,
            'Science' => 9
        )
    )
);

First, get all the subjects (English, Maths, Science, etc) that need to be displayed:

$columns = array();

foreach ($rows as $row) {
    foreach ($row as $roll => $set) {
        foreach ($set as $class => $score) {
            $columns[$class] = $class;
        }
    }
}

Then, display them (quick and dirty):

<table border="1">
    <thead>
        <tr>
            <th>Roll No</th>
        <?php
            foreach ($columns as $column) {
                echo '<th>' . $column . '</th>';
            }
        ?>
        </tr>
    </thead>
    <tbody>
    <?php
        foreach ($rows as $row) {
            echo '<tr>';
            foreach ($row as $roll => $set) {
                echo '<td>' . $roll . '</td>';
                foreach ($columns as $class) {
                    echo '<td>' . ((array_key_exists($class, $set)) ? $set[$class] : 'n/a') . '</td>';
                }
            }
            echo '</tr>';
        }
    ?>
    </tbody>
</table>
Sign up to request clarification or add additional context in comments.

3 Comments

you code works like a charm. But I am not sure whether it will break if the sorting is different. I would like you to explain bit more on how you come up with this. Thanks.
The order of the columns as they appear in the initial array ($rows in my answer) won't matter. Technically, it won't matter if "English", "Maths" and "Science" are in different orders in the arrays that contain them either. It would also work if additional values were added to that same array. (Because we are just getting all unique values, regardless of order.) The "order" of the columns will just depend on how they're first encountered in the first segment of code.
you really saved my day. Now I can happily code the clientside. Thank you very much.
1

"Quick" solution with array_walk, array_merge, array_values and array_keys functions:

// assuming that $arr is your initial array
$header_sequence = ['Science','Maths','English']; // if header's key sequence is dynamic
sort($header_sequence);

$result = [];
array_walk($arr, function($v, $k) use (&$result){    
    $key = array_keys($v)[0];
    $result[$k] = array_merge([$key], array_values($v[$key]));    
});

?>
<table>
  <thead>
   <tr>
      <th>Roll No</th>
      <?php foreach($header_sequence as $item): ?>
         <th><?= $item ?></th>
      <?php endforeach; ?>
  </tr>
  </thead>
  <tbody>
    <?php foreach($result as $k => $v): ?>
      <tr>
       <?php foreach($v as $item): ?>
          <td><?= $item ?></td>
       <?php endforeach; ?>
      </tr>
    <?php endforeach; ?>
  </tbody>

The output:

Roll No English Maths Science
6       17      11    15
7       13      15    11
8       9       17    9

6 Comments

Thanks for another great way. But <th>English</th><th>Maths</th><th>Science</th> (table header) should be dynamic. Any way to do in your method? please help.
@MawiaHL, your initial array has a words sequence in proper alphabetical order English - Maths - Science.Though the table header can be dynamically generated, but it doesn't have to be dynamic on the output. So if I have got a dynamically generated words sequence - I would sort it anyway (e.g. sort function)
please update your answer with dynamically generated header. The previous answer did generated but it generated three times. Thanks.
Note that table header should not be dynamic on every iteration through the array which contains data for every next table row. It should be filled at once for a certain table. In this situation, it should be considered as just once dynamically generated sequence before table's constructing. Besides, Roll No should not be presented in that dynamic sequence, because row number should always be the first table column!
Yes, I understand that. But how do I generate the header for once so that English Maths Science be used as headers excluding Rollno.? help me. please.
|
1

Please try this,

<table>
  <thead>
   <tr>
     <th>Roll No</th>
     <?php foreach($arrays as $k1=>$val1): ?>
       <?php foreach($val1 as $k2=>$val2): ?>
         <?php foreach($val2 as $k3=>$val3): ?>
           <th><?=$k3?></th>
         <?php endforeach; ?>
       <?php break; endforeach; ?>
     <?php break; endforeach; ?>
  </tr>
  </thead>
  <tbody>
    <?php foreach($arrays as $k1=>$val1): ?>
      <tr>
       <?php foreach($val1 as $k2=>$val2): ?>
        <th><?=$k2?></th>
        <th><?=$val2['English']?></th>
        <th><?=$val2['Maths']?></th>
        <th><?=$val2['Science']?></th>
       <?php endforeach; ?>
      </tr>
    <?php endforeach; ?>
  </tbody>
  </table>

As you have little complex array, we have to run foreach 2 time, 1st to generate <tr> 3 time and 2nd to display records.

For th we have to make roll number static because we have no strong in array for that.

9 Comments

Thanks for quick answer. But I need to loop the table header as well. That's where the problem come.
Why you want to loop table header?
You did not mentioned anything regarding dynamic header in your question, can you update your question again? so i know what you exact want.
ok but roll number will remain static, as you have no sting of that in array.and subject should be fixed in all array.
ok np, but suppose first sub array has order like this english,maths,science, then all other sub array has to be in same order.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.