Looping through array of unlimited children and display to a table - php

I don't have any idea how to loop through this array and display it to an HTML table. Child data are dynamic and can be unlimited. Anyone can give me a clue? Thanks!
(
[0] => Array
(
[Discount] => Array
(
[id] => 8
[parent_id] => 0
[lft] => 1
[rght] => 6
[name] => Discount 1
[value] => 25
)
[children] => Array
(
[0] => Array
(
[Discount] => Array
(
[id] => 10
[parent_id] => 8
[lft] => 2
[rght] => 5
[name] => Child of D1
[value] => 32
)
[children] => Array
(
[0] => Array
(
[Discount] => Array
(
[id] => 11
[parent_id] => 10
[lft] => 3
[rght] => 4
[name] => The 1.1.1
[value] => 65
)
[children] => Array
(
)
)
)
)
)
)
)
I know I can't just do:
foreach($discounts as $discount){
echo "<div>{$discount['Discount']['name']}</div>";
}

Try this
foreach ($Discount as $children => $value) {
echo "<div>{$discount['Discount']['$children']['name']}</div>";
}

You will need recursion to properly generate the HTML. Here is an example that I hope is helpful. This isn't exactly HOW you'll want to generate the final HTML but this should get you started on the right track:
$data = array(
0 => array(
'discount' => array(
'id' => 8,
'parent_id' => 0,
'lft' => 1,
'rght' => 6,
'name' => 'Discount 1',
'value' => 25,
),
'children' => array(
0 => array(
'discount' => array(
'id' => 10,
'parent_id' => 8,
'lft' => 2,
'rght' => 5,
'name' => 'Child of D1',
'value' => 32,
),
'children' => array(
0 => array(
'discount' => array(
'id' => 11,
'parent_id' => 10,
'lft' => 3,
'rght' => 4,
'name' => 'The 1.1.1',
'value' => 65,
),
'children' => array(),
)
)
)
)
)
);
$html = getHtml($data);
/**
* This function is called recursively to generate the necessary HTML
* #param array $data
*/
function getHtml(array $data)
{
// This is your base conditon to end the recursion. It stops once it hits an empty children array
if (empty($data)) {
return;
}
$data = $data[0]; // will have to tweak this if you have more than 1 element per array
$html = sprintf('<div id="%d" name="%s">', $data['discount']['id'], $data['discount']['name']);
$html .= getHtml($data['children']); // this recursive call generates inner HTML
$html .= '</div>';
return $html;
}
// See the result
var_dump($html);

Related

How to get Php multidimensional array same key’s same value’s related total in new array?

Php multidimensional array same key’s same value’s related total in
new array. I have an array of following mentioned. i need new array
as total qty of same item_id. anyone can help would be appreciate.
My Original Array is as following
Array
(
[a] => Array
(
[item] => Array
(
[item_id] => 1
)
[qty] => 0
),
[b] => Array
(
[item] => Array
(
[item_id] => 2
)
[qty] => 35
),
[c] => Array
(
[item] => Array
(
[item_id] => 2
)
[qty] => 15
),
[e] => Array
(
[item] => Array
(
[item_id] => 3
)
[qty] => 20
),
);
I want array Output like following :
Array(
[0] => Array (
[item_id] => 1,
[item_total_qty] => 0,
)
[1] => Array (
[item_id] => 2,
[item_total_qty] => 50,
)
[2] => Array (
[item_id] => 3,
[item_total_qty] => 20,
)
);
Hope it help
$arrays = array(
'a' => array(
'item' => array(
'item_id' => 1
),
'qty' => 0
),
'b' => array(
'item' => array(
'item_id' => 2
),
'qty' => 35
),
'c' => array(
'item' => array(
'item_id' => 2
),
'qty' => 15
),
'd' => array(
'item' => array(
'item_id' => 3
),
'qty' => 20
)
);
$result = array();
foreach ($arrays as $key => $array) {
if (is_array($result) && !empty($result)) {
foreach ($result as $key => $r) {
if ($r['item_id'] == $array['item']['item_id']) {
$result[$key]['item_total_qty'] += $array['qty'];
continue 2;
}
}
$result[] = array(
'item_id' => $array['item']['item_id'],
'item_total_qty' => $array['qty']);
} else {
$result[] = array(
'item_id' => $array['item']['item_id'],
'item_total_qty' => $array['qty']);
}
}
Simple foreach on your original table:
$sorted = array();
foreach ($original as $item) {
$id = $item['item']['item_id'];
$sorted[$id]['item_total_qty'] = $sorted[$id] ? $sorted[$id] + $item['qty'] : item['qty'];
$sorted[$id]['item_id'] = $id;
}
$sorted = array_values($sorted);

Print associative array to table

I have an associative array like this, i want to generate a table with these data, like breakfast, snacks, lunch, supper, dinner in row the following is the code I've tried, but I am stuck where to break the table row because when the array contains more than one item.i wants to Print associative array to table
*--------------------------------------------------*
| **Breakfast Snacks Lunch Supper Dinner** |
| test test test testfrom
|testfrom
*--------------------------------------------------*
array output is as follow
Array
(
[meal_plan_id] => 17
[calorie_limit] => 1
[total_calorie] => 0
[date] => 2017-12-29
[meal_plan] => Array
(
[0] => Array
(
[meal_type] => bf
[label] => Breakfast
[calorie_limit] => 30
[total_calorie] => 0
[data] => Array
(
[0] => Array
(
[id] => 107
[label] => test
[quantity] => 10
[unit] => g
[status] => bf
)
[1] => Array
(
[id] => 109
[label] => testfrom
[quantity] => 12
[unit] => g
)
)
)
[1] => Array
(
[meal_type] => sn
[label] => Snacks
[calorie_limit] => 10
[total_calorie] => 0
[data] => Array
(
[0] => Array
(
[id] => 108
[label] => test
[quantity] => 121
[unit] => g
)
)
)
[2] => Array
(
[meal_type] => lu
[label] => Lunch
[calorie_limit] => 20
[total_calorie] => 0
[data] => Array
(
[0] => Array
(
[status] => su
)
)
)
[3] => Array
(
[meal_type] => su
[label] => Supper
[calorie_limit] => 30
[total_calorie] => 0
[data] => Array
(
[0] => Array
(
[status] => sn
)
[1] => Array
(
[id] => 116
[label] => test
[quantity] => 200
[unit] => oz
)
)
)
[4] => Array
(
[meal_type] => dn
[label] => Dinner
[calorie_limit] => 20
[total_calorie] => 0
[data] => Array
(
[0] => Array
(
[id] => 113
[label] => test500
[quantity] => 20
[unit] => oz
[status] => dn
)
)
)
)
)
below is the code I've tried
// $daily_meals = show_daily_meals() // contains the array
if(!empty($daily_meals['meal_plan'])){
echo '<tr>';
foreach($daily_meals['meal_plan'] as $meal_plan){
foreach ($meal_plan['data'] as $data){
if(!empty($data['id']))
echo '<td class="'.$meal_type.'" data-meals-id="'.$data['id'].'"><span class="left">'.$data['label'].'</span> <span class="right">'.$data['quantity'].' <a class="delete_row"><i class="fa fa-trash" aria-hidden="true"></i></a></span><div class="row_loader"></div></td>';
else echo '<td></td>';
}
$i++;
if($i%5 == 0) echo '</tr>';
}
}
Here is your solution
Input
<?php
$array = array(
array(
'meal_type' => 'bf',
'label' => 'Breakfast',
'calorie_limit' => 30,
'total_calorie' => 0,
'data' => array(
array(
'id' => 107,
'label' => 'test',
'quantity' => 10,
'unit' => 'g',
'status' => 'bf'
),
array(
'id' => 109,
'label' => 'testfrom',
'quantity' => 12,
'unit' => 'g'
)
)
),
array(
'meal_type' => 'sn',
'label' => 'Snacks',
'calorie_limit' => 10,
'total_calorie' => 0,
'data' => array(
array(
'id' => 108,
'label' => 'test',
'quantity' => 121,
'unit' => 'g'
)
)
),
array(
'meal_type' => 'lu',
'label' => 'Lunch',
'calorie_limit' => 20,
'total_calorie' => 0,
'data' => array(array('status' => 'su'))
),
array(
'meal_type' => 'su',
'label' => 'Supper',
'calorie_limit' => 30,
'total_calorie' => 0,
'data' => array(
array('status' => 'sn'),
array(
'id' => 116,
'label' => 'test',
'quantity' => 200,
'unit' => 'oz'
),
)
),
array(
'meal_type' => 'dn',
'label' => 'Dinner',
'calorie_limit' => 20,
'total_calorie' => 0,
'data' => array(
array(
'id' => 113,
'label' => 'test500',
'quantity' => 20,
'unit' => 'oz',
'status' => 'dn'
)
)
)
);
Solution
1st foreach for parent array. Then second for its child..
foreach($array as $r){
$$r['label'] = '<table width="100%">';
foreach($r['data'] as $s){
if(isset($s['label']))$$r['label'] .= '<tr><td align="center">'.$s['label'].'</td></tr>'; // The if condition check weather the label is exist or not if yes then add that in particular label's table
}
$$r['label'] .= '</table>';
}
echo '
<table width="100%" border="1">
<thead>
<tr>
<th>Breakfast</th>
<th>Snacks</th>
<th>Lunch</th>
<th>Supper</th>
<th>Dinner</th>
</tr>
</thead>
Here all labels canverted into variable by $$r['label']. And all have there own table Now we add all these tables into the master table to get the output.
<tbody>
<tr>
<td>'.$Breakfast.'</td>
<td>'.$Snacks.'</td>
<td>'.$Lunch.'</td>
<td>'.$Supper.'</td>
<td>'.$Dinner.'</td>
</tr>
</tbody>
</table>';
//?// echo "<pre>";print_r($array);
?>
Output
Try storing all your column names in an array and create a table with it:
foreach($array as $row) {
$column[$i]['label'] = $row['label'];
$column[$i]['data'] = $this->getdata($row['data']);
$i++;
}
function getdata($array) {
$data = '';
foreach($array as $row) {
$data. = $row['label'].',';
}
return $data;
}
Create a table with the column names and try inserting data using a loop with respect to insert into

PHP - (Almost) Flatten multidimensional array recursively

I am trying to change the following array to an almost flat array. So id 4 would be in the first level of the array, as would id 6 and 5, but still have their own index so I can tell which page is which. But with the same order as they have now. I presume that the solution would be some sort of recursive PHP function but I haven't a clue how to do this.
Array
(
[0] => Array
(
[id] => 2
[identifier] => External URL
[parent] => 0
[sortOrder] => 1
[depth] => 0
)
[1] => Array
(
[id] => 3
[identifier] => First Team
[parent] => 0
[sortOrder] => 2
[depth] => 0
[children] => Array
(
[0] => Array
(
[id] => 4
[identifier] => League tables
[parent] => 3
[sortOrder] => 0
[depth] => 1
[children] => Array
(
[0] => Array
(
[id] => 6
[identifier] => British and Irish Cup Tables
[parent] => 4
[sortOrder] => 24
[depth] => 2
)
[1] => Array
(
[id] => 5
[identifier] => Greene King IPA Championship
[parent] => 4
[sortOrder] => 25
[depth] => 2
)
)
)
)
)
[2] => Array
(
[id] => 1
[identifier] => Home
[parent] => 0
[sortOrder] => 25
[depth] => 0
)
)
<?php
$data = [
[
'id' => 1,
'name' => 'one',
'children' =>
[
[
'id' => 2,
'name' => 'two',
'children' =>
[
[
'id' => 4,
'name' => 'four'
]
]
],
[
'id' => 3,
'name' => 'three',
'children' =>
[
[
'id' => 5,
'name' => 'five'
]
]
]
]
],
[
'id' => 6,
'name' => 'six'
]
];
$stanley = [];
$flatten = function(array $data) use (&$flatten, &$stanley) {
foreach($data as $k => $v) {
if(isset($v['children'])) {
$flatten($v['children']);
unset($v['children']);
}
$stanley[] = $v;
}
};
$flatten($data);
var_export($stanley);
Output:
array (
0 =>
array (
'id' => 4,
'name' => 'four',
),
1 =>
array (
'id' => 2,
'name' => 'two',
),
2 =>
array (
'id' => 5,
'name' => 'five',
),
3 =>
array (
'id' => 3,
'name' => 'three',
),
4 =>
array (
'id' => 1,
'name' => 'one',
),
5 =>
array (
'id' => 6,
'name' => 'six',
),
)
I have found the solution! I built a recursive PHP function which utilised the depth index to track which level each of the items are while still keeping the array flat (ish).
function dropdownNavigationTree($array) {
$response = [];
foreach($array as $page) {
if (!is_array($page['children'])) {
$response[$page['id']] = ($page['depth'] > 0 ? str_repeat("-", $page['depth']).' ' : FALSE).$page['identifier'];
} else {
$response[$page['id']] = ($page['depth'] > 0 ? str_repeat("-", $page['depth']).' ' : FALSE).$page['identifier'];
$children = dropdownNavigationTree($page['children']);
$response = $response + $children;
}
}
return $response;
}

Format a nested set model result into PHP array

Looking to create a function which arrangesmy nested set model into an array based on levels (categories[0], sub_categories[1], types[2]).
categories[0]
Alcohol |
| sub_categories[1]
|—————Beer
|
|—————Spirts
|
|—————Cider
|
|—————Wine
| |
| | types[2]
| |—————White wine
| |
| |—————Red wine
|
Bvrages |
| sub_categories[1]
|————— Soft Drinks
I was having a look at an older post and it got me close but only transferred the title and not the whole array How do I format Nested Set Model data into an array?.
What i want to achieve is a similar structure like above. Just remember i want to move all data not just the title.
My current output from my query is as follows:
Array
(
[0] => Array
(
[id] => 1
[title] => alcohol
[level] => 0
[uri] => alcohol
[count] => 100
)
[1] => Array
(
[id] => 2
[title] => beer
[level] => 1
[uri] => beer
[count] => 50
)
[2] => Array
(
[id] => 3
[title] => cider
[level] => 1
[uri] => cider
[count] => 20
)
[3] => Array
(
[id] => 4
[title] => wine
[level] => 1
[uri] => wine
[count] => 20
)
[4] => Array
(
[id] => 6
[title] => white wine
[level] => 2
[uri] => white-wine
[count] => 5
)
[5] => Array
(
[id] => 7
[title] => red wine
[level] => 2
[uri] => red-wine
[count] => 15
)
[6] => Array
(
[id] => 8
[title] => spirits
[level] => 1
[uri] => spirits
[count] => 5
)
[7] => Array
(
[id] => 9
[title] => Beverages
[level] => 0
[uri] => beverages
[count] => 50
)
[8] => Array
(
[id] => 10
[title] => soft drinks
[level] => 1
[uri] => soft-drink
[count] => 10
)
)
Any thoughts?
Try to use this code:
<?php
//Represent your array like this (you may include other data to the each item)
//array must be ordered by 'left' field:
$data = array(
array("left" => 1, "right" => 10, "name" => "P0"),
array("left" => 2, "right" => 7, "name" => "P1"),
array("left" => 3, "right" => 4, "name" => "P11"),
array("left" => 5, "right" => 6, "name" => "P12"),
array("left" => 8, "right" => 9, "name" => "P2")
);
//Converter function gets nested sets array and returns nested php array
function nest($arrData){
$stack = array();
$arraySet = array();
foreach( $arrData as $intKey=>$arrValues) {
$stackSize = count($stack);
while($stackSize > 0 && $stack[$stackSize-1]['right'] < $arrValues['left']) {
array_pop($stack);
$stackSize--;
}
$link =& $arraySet;
for($i=0;$i<$stackSize;$i++) {
$link =& $link[$stack[$i]['id']]["children"]; //navigate to the proper children array
}
$tmp = array_push($link, array ('item'=>$arrValues,'children'=>array()));
array_push($stack, array('id' => $tmp-1, 'right' => $arrValues['right']));
}
return $arraySet;
}
//Print result
printArray(nest($data));
function printArray($array){
echo "<ul>";
foreach ($array as $row){
$children = $row['children'];
echo "<li>";
echo $row['item']['name'];
if (!empty($children)) printArray($children);
echo "</li>";
}
echo "</ul>";
}
?>
If I understood you right, then try this solution:
<?php
$data=Array(
0 => Array(
'id' => 1,
'title' => 'alcohol',
'level' => 0,
'uri' => 'alcohol',
'count' => 100,
),
1 => Array(
'id' => 2,
'title' => 'beer',
'level' => 1,
'uri' => 'beer',
'count' => 50,
),
2 => Array(
'id' => 3,
'title' => 'cider',
'level' => 1,
'uri' => 'cider',
'count' => 20,
),
3 => Array(
'id' => 4,
'title' => 'wine,',
'level' => 1,
'uri' => 'wine',
'count' => 20,
),
4 => Array(
'id' => 6,
'title' => 'white wine',
'level' => 2,
'uri' => 'white-wine',
'count' => 5,
),
5 => Array(
'id' => 7,
'title' => 'red wine',
'level' => 2,
'uri' => 'red-wine',
'count' => 15,
),
6 => Array(
'id' => 8,
'title' => 'spirits',
'level' => 1,
'uri' => 'spirits',
'count' => 5,
),
7 => Array(
'id' => 9,
'title' => 'Beverages',
'level' => 0,
'uri' => 'beverages',
'count' => 50,
),
8 => Array(
'id' => 10,
'title' => 'soft drinks',
'level' => 1,
'uri' => 'soft-drink',
'count' => 10,
)
);
$cats=array();
$prev_level=1;
$index0='';
$index1=0;
foreach($data as $dat){
switch($dat['level']){
case 0:
$cats[$dat['uri']]=array(
'name'=>$dat['title'],
'sub_categories'=>array()
);
$index0=$dat['uri'];
break;
case 1:
if($prev_level<1)
$index1=0;
else
$index1++;
$cats[$index0]['sub_categories'][$index1]=array(
'name'=>$dat['title']
);
break;
case 2:
if($prev_level<2){
$cats[$index0]['sub_categories'][$index1]['types']=array();
}
$cats[$index0]['sub_categories'][$index1]['types'][]=$dat['title'];
break;
}
$prev_level=$dat['level'];
}
print_r($cats);
?>

Have the following array merged

I have the following array:
Array
(
[0] => Array
(
[Vendor_ID] => 1
[Quantity] => 55
)
[1] => Array
(
[Vendor_ID] => 1
[Quantity] => 55
)
[2] => Array
(
[Vendor_ID] => 1
[Quantity] => 55
)
[3] => Array
(
[Vendor_ID] => 3
[Quantity] =>
)
[4] => Array
(
[Vendor_ID] => 3
[Quantity] =>
)
[5] => Array
(
[Vendor_ID] => 3
[Quantity] =>
)
[6] => Array
(
[Vendor_ID] => 4
[Quantity] =>
)
[7] => Array
(
[Vendor_ID] => 4
[Quantity] =>
)
[8] => Array
(
[Vendor_ID] => 4
[Quantity] =>
)
)
Which is being created with the following code:
$Display_Arr = array();
$Tick = 0;
foreach ($_POST['product'] AS $_1){
if (!in_array($_1['vendor_id'], $Display_Arr)){
$Display_Arr[$Tick] = array(
"Vendor_ID" => $_1['vendor_id'],
"Quantity" => ""
);
$Display_Arr[$Tick]["Quantity"] .= $_1['quantity'];
}else{
$Display_Arr[$Tick]["Quantity"] .= $_1['quantity'];
}
++$Tick;
}
echo "<pre>";
print_r($Display_Arr);
echo "</pre>";
But I am not getting my desired output, which is:
Array
(
[0] => Array
(
[Vendor_ID] => 1
[Quantity] => 55,55,55
)
[1] => Array
(
[Vendor_ID] => 3
[Quantity] =>
)
[2] => Array
(
[Vendor_ID] => 4
[Quantity] =>
)
)
Where am I going wrong with this?
#mathielo
The current output is:
Array
(
[1] => Array
(
[Vendor_ID] => 1
[Quantity] => 55
)
[3] => Array
(
[Vendor_ID] => 3
[Quantity] =>
)
[4] => Array
(
[Vendor_ID] => 4
[Quantity] =>
)
)
Whereas, i'm trying to obtain:
[0] => Array
(
[Vendor_ID] => 1
[Quantity] => 55,55,55
)
If I got it right, what you need is this:
EDIT: Just made some tests and got it right this time:
$Display_Arr = array();
foreach ($_POST['product'] AS $_1){
if (!array_key_exists($_1['Vendor_ID'], $Display_Arr)){
$Display_Arr[$_1['Vendor_ID']] = array(
"Vendor_ID" => $_1['Vendor_ID'],
"Quantity" => $_1['Quantity']
);
}else{
if(!empty($_1['Quantity']))
$Display_Arr[$_1['Vendor_ID']]["Quantity"] .= ",{$_1['Quantity']}";
}
}
echo "<pre>";
print_r($Display_Arr);
echo "</pre>";
The main problem was in if (!in_array($_1['vendor_id'], $Display_Arr)). PHP's in_array() checks for given needle in the array values, and we were trying to match to the Vendor_ID value stored in the outer array keys. That was fixed using array_key_exists().
EDIT 2: I used this for test data:
$_POST['product'] = array(
0 => array(
'Vendor_ID' => 1,
'Quantity' => 55
),
1 => array(
'Vendor_ID' => 1,
'Quantity' => 55
),
2 => array(
'Vendor_ID' => 1,
'Quantity' => 55
)
,
3 => array(
'Vendor_ID' => 3,
'Quantity' => ''
),
4 => array(
'Vendor_ID' => 3,
'Quantity' => ''
),
5 => array(
'Vendor_ID' => 3,
'Quantity' => ''
),
6 => array(
'Vendor_ID' => 4,
'Quantity' => ''
),
7 => array(
'Vendor_ID' => 4,
'Quantity' => ''
),
8 => array(
'Vendor_ID' => 4,
'Quantity' => ''
)
);
You won't be needing $Tick anymore, as you could use Vendor_ID as keys for the outer array.
Looks like the easiest way to solve this would be to first aggregate the vendor quantities, and then build the final array with the keys that you are using.
I am assuming the input looks something like this:
$_POST['product'] = [
['vendor_id' => 1, 'quantity' => 55],
['vendor_id' => 1, 'quantity' => 55],
['vendor_id' => 1, 'quantity' => 55],
['vendor_id' => 3, 'quantity' => null],
['vendor_id' => 3, 'quantity' => null],
['vendor_id' => 3, 'quantity' => null],
['vendor_id' => 4, 'quantity' => null],
['vendor_id' => 4, 'quantity' => null],
['vendor_id' => 4, 'quantity' => null],
];
Aggregating the quantities:
$aggregates = [];
foreach ($_POST['product'] as $product) {
$id = $product['vendor_id'];
if ( ! isset($aggregates[$id])) {
$aggregates[$id] = [];
}
if ($product['quantity'] > 0) {
$aggregates[$id][] = $product['quantity'];
}
}
The aggregates array should now look like this:
$aggregates = [
1 => [
0 => 55,
1 => 55,
2 => 55,
],
3 => [], // Empty
4 => [], // Empty
];
As you can see the data is now neatly organized and ready to be put into any format you want. Using the keys that you use in your question it is as simple as:
$output = [];
foreach ($aggregates as $vid => $qty) {
$quantity = implode(',', $qty);
$output[] = ['Vendor_ID' => $vid, 'Quantity' => $quantity];
}
The output should now look like this:
$output = [
['Vendor_ID' => 1, 'Quantity' => '55,55,55'],
['Vendor_ID' => 3, 'Quantity' => ''],
['Vendor_ID' => 4, 'Quantity' => ''],
];
This will output exactly what you are looking for although the output of the last answer (Sverri M. Olsen) is more useful. Here you get the quantities as a string while with Sverri's method you get an array in first place.
$Display_Arr = array();
$vendors=array();
foreach ($_POST['product'] AS $_1){
if (!in_array($_1['vendor_id'],$vendors)){
$vendors[]=$_1['vendor_id'];
$Display_Arr[sizeof($vendors)-1] = array(
"Vendor_ID" => $_1['vendor_id'],
"Quantity" => $_1['quantity']
);
}
else{
$vendorKey=array_search($_1['vendor_id'],$vendors);
$Display_Arr[$vendorKey]["Quantity"] .=(!empty($Display_Arr[$vendorKey]["Quantity"])?',':null).$_1['quantity'];
}
}

Categories