1

I have nested foreach loops to show MySQL records in nested array.

while ($row = mysql_fetch_array($result)) {
    $departments[$row['department_name']][$row['group_name']][] = $row['lab_test'] . ',' . $row['result'] . ',' . $row['um'] . ',' . $row['reference_interval'];
}

  foreach($departments as $department_name => $groups){
    echo "<tr class='department'><td>" . $department_name . "</td></tr>";
        foreach($groups as $group_name => $tests){
               echo "<tr class='test_group'><td>" . $group_name . "</td></tr>";
                   foreach($tests as $test){
                          list($test_name, $test_result, $test_um, $test_interval) = explode(',', $test);   

echo "<tr class='test_item'><td>" . $test_name . "</td><td>" . $test_result . "</td><td>" . $test_um . "</td><td>" . $test_interval . "</td></tr>";
                   }
    }
    echo "<tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr>";
}

This works OK, but I want to change it so that $group_name only shows if it is not equal to $test_name. The problem being $test_name is not initiated until the next foreach loop.

IlludiumPu36
  • 3,998
  • 8
  • 52
  • 87

3 Answers3

1

I didn't think of duplicating the foreach loop to get $test_name values earlier in the logic. This works, but it seems kind of messy, but it works...

foreach($departments as $department_name => $groups){
    echo "<tr class='department'><td>" . $department_name . "</td></tr>";
        foreach($groups as $group_name => $tests){
            foreach($tests as $test){
                          list($test_name, $test_result, $test_um, $test_interval) = explode(',', $test);   
            }
            if($group_name != $test_name){
               echo "<tr class='test_group'><td>" . $group_name . "</td></tr>";
            }
                   foreach($tests as $test){
                          list($test_name, $test_result, $test_um, $test_interval) = explode(',', $test);   
IlludiumPu36
  • 3,998
  • 8
  • 52
  • 87
1

First off, take a serious look at your code structure. 3 nested foreach loops is generally not good practice.

I'd suggest re-writing this to take advantage of the stdClass in PHP.

A re-write would accomplish what you're looking for rather quickly:

while ($row = mysql_fetch_array($result)) {
  $resultObj = new stdClass();
  $resultObj->department_name = $row['department_name'];
  $resultObj->group_name = $row['group_name'];
  $resultObj->lab_test = $row['lab_test'];
  ...etc
  $results[] = $resultObj;
}

foreach($results as $result) {
  if ($resultObj->group_name != ($resultObj->lab_test . "," . $resultObj->result . "," . $resultObj->um . "," . $resultObj->reference_interval)) {
    // the group_name is not equal to the concatenated string above
    // so here is where you would echo your table row
}

I'd also look into the table format that you have. For readability, you'll want to use colspan on the trs that contain the group_name and department

Community
  • 1
  • 1
Adam Link
  • 2,705
  • 4
  • 26
  • 44
  • Thanks for this...looks much cleaner and manageable...I'll give it a go. – IlludiumPu36 Mar 19 '15 at 02:46
  • I can't see how you could get tests to display under their associated test group names...that was why I was using nested foreach loops. – IlludiumPu36 Mar 19 '15 at 02:50
  • I understand why, but there is a cleaner way to do what you're trying to do. One of the biggest things you can do, if you have a list of the test names as separate data, is to put those test names into a different array, rather than having them in the `$departments` array. So you'd have `$departments` and `$test_group_names` – Adam Link Mar 19 '15 at 02:52
0

I am suggest this code to use before third foreach.

if($group_name != $tests[$group_name][0])
  echo "<tr class='test_group'><td>" . $group_name . "</td></tr>";
Eranda
  • 754
  • 1
  • 9
  • 23