zkanoca
zkanoca

Reputation: 9918

How to correctly list items in different categories? General programming technique

I have a datatable which contains items and their categories. I want to list them as the following.

<h3>CATEGORY 1</h3>
<ul>
    <li>item 1</li>
    <li>item 2</li>
    <li>item 3</li>
</ul>

<h3>CATEGORY 2</h3>
<ul>
    <li>item 10</li>
    <li>item 20</li>
    <li>item 30</li>
</ul>

My actual data looks like below:

$table =  array(
             array(
                "cat" => "Vegetables",
                "item" => "mydonose"
             ),
             array(
                 "cat" => "Vegetables",
                 "item" => "carrot"
             ),
              array(
                "cat" => "Vegetables",
                "item" => "tomato"
                ),
             array(
                 "cat" => "Fruits",
                 "item" => "apple"
             ),
              array(
                "cat" => "Fruits",
                "item" => "banana"
                ),
             array(
                 "cat" => "Fruits",
                 "item" => "orange"
             ),
              array(
                "cat" => "Other",
                "item" => "mushroom"
                ),
             array(
                 "cat" => "Other",
                 "item" => "olive"
             )     
    );

I am trying to list data using the code below.

$cat = "";

foreach($table as $t):

    if($cat !== $t["cat"]):

        echo "<h3>".$t["cat"]."</h3>";
        echo "<ul>";
    endif;

    echo "<li>".$t["item"]."</li>";

    if($cat !== $t["cat"]):
        echo "</ul>"; //this part is problem
        $cat = $t["cat"];
    endif;            

endforeach;

But I cannot figure out on which condition I should echo </ul> closing tag. My final output should be like:

<h3>Vegetables</h3>
<ul>
    <li>mydonose</li>
    <li>carrot</li>
    <li>tomato</li>
</ul>
<h3>Fruits</h3>
<ul>
    <li>apple</li>
    <li>banana</li>
    <li>orange</li>
</ul>
<h3>Other</h3>
<ul>
    <li>mushroom</li>
    <li>olive</li>
</ul>

Upvotes: 0

Views: 54

Answers (4)

Yazan
Yazan

Reputation: 6082

i have noticed the selected answer, this sol works too and you don't have to create another array

more details are included in code comments.

foreach($table as $t):

//if first loop: print category, open a list, assign cat value
    if($cat==""){
        echo "<h3>".$t["cat"]."</h3>\n";
        echo "<ul>\n";
        $cat = $t["cat"];
    }

    //if still in same cat, add item to list
    if ($cat == $t["cat"]){
        echo "<li>".$t["item"]."</li>\n";
    }else{
    //if new cat, close list, print new cat, open new list, add current item to list, assign cat value
        echo "</ul>\n"; 
        echo "<h3>".$t["cat"]."</h3>\n";
        echo "<ul>\n";
        echo "<li>".$t["item"]."</li>\n";
        $cat = $t["cat"];
    }
endforeach;

Upvotes: 0

arcanine
arcanine

Reputation: 1953

<?php
$table =  array(
 array(
  "cat" => "Vegetables",
  "item" => "mydonose"
  ),
 array(
   "cat" => "Vegetables",
   "item" => "carrot"
   ),
   ...
 );

// Key data by the category.
function group_table($carry, $value) {
  $carry[$value['cat']][] = array('item' => $value['item']);
  return $carry;
}

// Output the category and its child items.
function output_category($items, $category) {
  return '<h3>' . $category . '</h3>'
    . (count($items) ? '<ul>'
    .  implode('', array_map('output_items', $items))
    . '</ul>' : '');
}

// Output individual category items.
function output_items($item) {
  return '<li>' . $item . '</li>';
}

// Regroup data by key.
$grouped_table_data = array_reduce($table, 'group_table', []);

// Apply UI function to data.
$output = array_map('output_category', $grouped_table_data, array_keys($grouped_table_data));

// Print to screen.
print implode('', $output);

Upvotes: 0

Troyer
Troyer

Reputation: 7013

Using your code:

$cat = "";

foreach($table as $t):

    if($cat != $t["cat"]):
        if(strlen($cat) >  1) {
            echo "</ul>";
        }
        $cat = $t["cat"];
        echo "<h3>".$t["cat"]."</h3>";
        echo "<ul>";
    endif;

    echo "<li>".$t["item"]."</li>";


endforeach;

Upvotes: 1

Suchit kumar
Suchit kumar

Reputation: 11859

try like this:

$arr=array();
foreach($table as $key=>$val){
    $arr[$val['cat']][]=$val['item'];
}


foreach($arr as $key=>$val){
    echo "<h3>$key</h3>";
    if(sizeof($val) > 0){
    echo "<ul>";
    foreach($val as $key1=>$val1){
        echo "<li>$val1</li>";
    }
    echo "</ul>";
    }
}

Upvotes: 2

Related Questions