Reputation: 9918
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
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
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
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
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