Loop in a multidimensional array and its subarray with PHP - php

I've the following array:
$items = array(
array(
'name' => 'Item 1',
'desc' => 'Lorem ipsum...',
'rates' => array(
'Yes' => 50,
'No' => 75
)
),
array(
'name' => 'Item 2',
'desc' => 'Lorem ipsum...',
'rates' => array(
'Yes' => 50,
'No' => 0
)
)
);
How can I loop between the rates ?
Here what I tried:
foreach ($items as $item) {
foreach($item['rates'] as $rate => $value){
echo $rate['rates'];
}
}
Thanks.

change your code to
foreach ($items as $item) {
foreach($item['rates'] as $rate => $value){
echo $value;echo '<br/>';
}
}
in second loop $rate is key and $value have the current value of that key.

To keep (and continue) your work:
foreach ($items as $item) {
echo "Number of ratings for item: {$item['name']}<br/>";
foreach($item['rates'] as $rateKey => $rateValue) {
echo " - {$rateKey}: {$rateValue}<br/>";
}
}
Output:
Number of ratings for item: Item 1
- Yes: 50
- No: 75
Number of ratings for item: Item 2
- Yes: 50
- No: 0

foreach ($items as $item) {
foreach($item['rates'] as $rate => $value){
echo 'Rate is ' . $rate . '; value is ' . $value . '<br />';
}
}

Loop within loop is way slower than looping and it would only become noticeable when array that you're looping gets bigger. So one approach you could take is given below:
$items = array(
array(
'name' => 'Item 1',
'desc' => 'Lorem ipsum text',
'rates' => array(
'Yes' => 50,
'No' => 75
)
),
array(
'name' => 'Item 2',
'desc' => 'Lorem ipsum text',
'rates' => array(
'Yes' => 50,
'No' => 0
)
)
);
$rates = array_column($items, 'rates');
foreach($rates as $key => $value) {
if($value['Yes']) {
echo " Yes: {$value['Yes']}<br/>";
}
echo " No: {$value['No']}<br/><br/>";
}
Result:
Yes: 50
No: 75
Yes: 50
No: 0

Related

Looping thru array for sum of one element

I have a shopping cart with three items like this:
$cart = [
1031 => [
'id' => '1031',
'model' => 'tr16',
'price' => 100,
'discount_applied' => '',
'promo_name' => '',
'promo_id' => ''
],
1032 => [
'id' => '1032',
'model' => 'tr16g',
'price' => 100,
'discount_applied' => '',
'promo_name' => '',
'promo_id' => ''
],
1034 => [
'id' => '1034',
'model' => 'tr17g',
'price' => 100,
'discount_applied' => '',
'promo_name' => '',
'promo_id' => ''
]
];
I have an array of IDs representing items eligible for a discount like this:
$itemIds = [
0 => [
0 => 1031
],
1 => [
0 => 1032
]
];
I loop thru each array and change the price where the ID in $cart matches ID in $itemIds by applying a 20% discount, and also add new elements. That code looks like this:
foreach($cart as &$item) {
foreach($itemIds as $ids) {
foreach($ids as $key => $value) {
if ($item['id'] == $value)
{
$item['discount_applied'] = $item['price'] * 0.2;
$item['price'] = $item['price'] * .80;
$item['promo_name'] = 'Test promo';
$item['promo_id'] = 36;
}
}
}
}
Printing the cart to the screen before and after the loop shows it's working as expected.
However, I encounter a problem when trying to loop through the modified $cart and calculate the sum of individual discounts.
My loop looks like this:
$cart['total_discount'] = 0;
foreach($cart as $item)
{
$cart['total_discount'] += $item['discount_applied'];
}
echo 'Total discount:' . $cart['total_discount'];
I expect to see the sum of discounts = 40, but instead = 60. Printing the cart to the screen before and after the loop shows that items 1031 and 1032 have a value of 20 in discount_applied and that item 1034 has no value.
Any help in identifying where I have an error or errors is appreciated.
Here's all the code if you want to copy/paste.
$cart = [
1031 => [
'id' => '1031',
'model' => 'tr16',
'price' => 100,
'discount_applied' => '',
'promo_name' => '',
'promo_id' => ''
],
1032 => [
'id' => '1032',
'model' => 'tr16g',
'price' => 100,
'discount_applied' => '',
'promo_name' => '',
'promo_id' => ''
],
1034 => [
'id' => '1034',
'model' => 'tr17g',
'price' => 100,
'discount_applied' => '',
'promo_name' => '',
'promo_id' => ''
]
];
$itemIds = [
0 => [
0 => 1031
],
1 => [
0 => 1032
]
];
echo '<h2>Cart BEFORE discount</h2>'; echo '<pre>';print_r($cart); echo '</pre>';
foreach($cart as &$item) {
foreach($itemIds as $ids) {
foreach($ids as $key => $value) {
if ($item['id'] == $value)
{
$item['discount_applied'] = $item['price'] * 0.2);
$item['price'] = $item['price'] * .80;
$item['promo_name'] = 'Test promo';
$item['promo_id'] = 36;
}
}
}
}
echo '<h2>Cart AFTER discount</h2>'; echo '<pre>';print_r($cart); echo '</pre>';
$cart['total_discount'] = 0;
foreach($cart as $item)
{
echo $item['discount_applied'] . '<br>';
$cart['total_discount'] += $item['discount_applied'];
}
echo 'Total discount:' . $cart['total_discount'];
Your use of &$item in the initial loop needs to be used in your final loop also. The loop where you adding up the discount total. You will also need to see if the discount value is a number since, in the code you posted, the 3rd item in the cart will have a blank value for the discount which will throw a non-numeric error when trying to add it to the discount total.
Your final loop modified to work:
$cart['total_discount'] = 0;
foreach($cart as &$item) {
echo '*' . $item['discount_applied'] . '*<br />'; // just to show what is or isn't there
$cart['total_discount'] += (is_numeric($item['discount_applied']) ? $item['discount_applied'] : 0);
}
echo 'Total discount:' . $cart['total_discount'];

Accumulative total foreach loop, using variable to group numbers [duplicate]

This question already has answers here:
multidimensional array array_sum
(10 answers)
Closed 5 years ago.
I need help regarding foreach and arrays in PHP
Say I have the following array:
$orders = array (
0 =>
array (
'company' => 'Company 1',
'total' => '5',
),
1 =>
array (
'company' => 'Company 2',
'total' => '10',
),
2 =>
array (
'company' => 'Company 1',
'total' => '15',
),
3 =>
array (
'company' => 'Company 1',
'total' => '5',
),
4 =>
array (
'company' => 'Company 3',
'total' => '12',
)
);
Order 1 is 5 for Company 1
Order 2 is 10 for Company 2
Order 3 is 15 for Company 1
Order 4 is 5 for Company 2
Order 5 is 12 for Company 3
I want the output to show the company name and the accumulative total of each company's orders
For example:
Company 1 20
Company 2 15
Company 3 12
Just create another array that will track the orders.
$companies = array();
foreach ($orders as $order) {
if (array_key_exists($order["company"], $companies)) {
$companies[$order["company"]] += $order["total"];
} else {
$companies[$order["company"]] = $order["total"];
}
}
First, we check if the company is already in the companies array, if it is then we add the total to that company's current total.
Otherwise, we just create a new key and store the total.
Additionally, you can write (int)$order["total"] to typecast into integer.
This might be useful to ensure that you have the correct data.
array_reduce() solution:
$groups = array_reduce($orders, function($r, $a) {
$k = $a['company'];
(isset($r[$k]))? $r[$k] += $a['total'] : $r[$k] = $a['total'];
return $r;
}, []);
foreach ($groups as $k => $v) {
printf("%-20s%d\n", $k, $v);
}
The output:
Company 1 25
Company 2 10
Company 3 12
One way to do this with a foreach loop where you increment some variable :
// Your array
$array = array(...);
// Init of the sum of each total for each company
$c1 = 0;
$c2 = 0;
$c3 = 0;
// You loop through your array and test the output
foreach ($array as $order => $value_array) {
switch($value_array['company']) {
case 'Company 1' : $c1 += intval($value_array['total']); break;
case 'Company 2' : $c2 += intval($value_array['total']); break;
case 'Company 3' : $c3 += intval($value_array['total']); break;
}
}
//$c1 will be the sum for company 1;
//$c2 for the company 2;
//$c3 for the company 3.
Is it what you are looking for?
Just another way: array_walk
$result = array();
array_walk($orders, function ($element) use (&$result) {
$company = $element['company'];
if (!isset($result[$company]))
$result[$company] = 0;
$result[$company] += $element['total'];
});
For this input:
$orders = array(
0 =>
array(
'company' => 'Company 1',
'total' => '5',
),
1 =>
array(
'company' => 'Company 2',
'total' => '10',
),
2 =>
array(
'company' => 'Company 1',
'total' => '15',
),
3 =>
array(
'company' => 'Company 1',
'total' => '5',
),
4 =>
array(
'company' => 'Company 3',
'total' => '12',
)
);
The output will be:
array(3) {
["Company 1"]=>
int(25)
["Company 2"]=>
int(10)
["Company 3"]=>
int(12)
}

multidimensional Array php

I am trying to build multidimensional to get json but its getting little complex. Sure there is easier way to do this. Here is my code.
$rows = array();
$idx = 0;
$sql = "SELECT products, GROUP_CONCAT(title,',' ,price SEPARATOR ', ' ) prods FROM mylist GROUP BY products";
$query = mysqli_query($con, $sql);
while($row = mysqli_fetch_assoc($query)){
$rows[$idx]['products'] = $row['products'];
$title = explode(',',$row['prods']);
$rows[$idx]['prods'] = $title;
$idx++;
};
echo '<pre>' . var_export($rows, true) . '</pre>';
echo json_encode($rows);
It give me this result
array (
0 =>
array (
'prods' =>
array (
0 => 'title 4',
1 => '4',
2 => ' title 1',
3 => '1',
),
),
1 =>
array (
'prods' =>
array (
0 => 'title 2',
1 => '21',
),
),
2 =>
array (
'prods' =>
array (
0 => 'title 3',
1 => '3',
),
),
)
[{"prods":["title 4","4"," title 1","1"]},{"prods":["title 2","21"]},{"prods":["title 3","3"]}]
But I want like this
array (
0 =>
array (
'prods' =>
array (
array(title => 'title 4', price => '4'),
array(title => ' title 1', price => '1'),
),
),
1 =>
array (
'prods' =>
array (
array(title => 'title 2', price => '21'),
),
),
2 =>
array (
'prods' =>
array (
array(title => 'title 3', price => '3'),
),
),
)
[
{
"prods": [
{
"title": "title 4",
"price": "4"
},
{
"title": "title1",
"price": "1"
}
]
},
{
"prods": [
{
"title": "title2",
"price": "21"
}
]
},
{
"prods": [
{
"title": "title3",
"price": "3"
}
]
}
]
So, not sure how to mix the exploded data on array to get the right json encoded.
You can do a foreach on the $title array and if the key is even then build the output array with the desired keys. In the below I edited to substituted your db query for json so that the full example can be included without the sql query.
$rows = array();
$idx = 0;
$data = json_decode('[{"products":"the product", "prods":"title 4,4,title 1,1"},{"products":"the product", "prods":"title 2,21"},{"products":"the product", "prods":"title 3,3"}]', true);
foreach ($data as $row)
{
$rows[$idx]['products'] = $row['products'];
$title = explode(',',$row['prods']);
foreach ($title as $k => $v) {
// check if even
if ($k % 2 == 0) $rows[$idx]['prods'][] = array('title' => $v, 'price' => $title[$k+1]);
}
$idx++;
};
echo '<pre>' . var_export($rows, true) . '</pre>';
echo json_encode($rows);
Will output the following
array (
0 =>
array (
'products' => 'the product',
'prods' =>
array (
0 => array ('title' => 'title 4','price' => '4'),
1 => array ('title' => 'title 1','price' => '1'),
),
),
1 =>
array (
'products' => 'the product',
'prods' =>
array (
0 => array ('title' => 'title 2','price' => '21'),
),
),
2 =>
array (
'products' => 'the product',
'prods' =>
array (
0 => array ('title' => 'title 3','price' => '3'),
),
),
)
Based on Tristan earlier suggestion, I was able to get the expected result with below code, not sure if that's the best way.
$rows = array();
$idx = 0;
$sql = "SELECT products, GROUP_CONCAT(title,',',price SEPARATOR ';') prods FROM mylist GROUP BY products";
$query = mysqli_query($con, $sql);
while($row = mysqli_fetch_assoc($query)){
$prods = explode(';',$row['prods']);
foreach ($prods as $key => $value) {
$expValue = explode(',',$value);
$rows[$idx]['prods'][] = array('title' => $expValue[0], 'price' => $expValue[1]);
};
$idx++;
};
echo '<pre>' . var_export($rows, true) . '</pre>';
echo json_encode($rows);

Combine array to one array

I have an array:
$settings = array(
'name' => array(
0 => 'Large Pouch',
1 => 'XL Pouch'
),
'size' => array(
0 => '9x14',
1 => '12x18'
),
'weight' => array(
0 => '10',
1 => '20'
),
'metro_manila_price' => array(
0 => '59',
1 => '79'
),
'luzvimin_price' => array(
0 => '89',
1 => '139'
)
);
I wanted to put the values from that array to one array. $shipping_options with format of
for example:
$shipping_options = array(
'0' => 'Large Pouch 9x14 - $59',
'1' => 'XL Pouch 12x18 - $79'
);
How to program this?
You could write a loop:
$shipping_options = array();
foreach ($settings['name'] as $key => $value) {
$value = sprintf('%s(%s) - $%s',
$value,
$settings['size'][$key],
$settings['metro_manila_price'][$key]);
$shipping_options[$key] = $value;
}
try this one
echo "<pre>";
$size = count($settings['name']);
$shipping_options = array();
for($i=0; $i<$size; $i++)
{
$shipping_options[$i] = $settings['name'][$i]."(".$settings['size'][$i].") - $".$settings['metro_manila_price'][$i];
}
print_r($shipping_options);
You can try this
foreach ($settings['name'] as $key => $value) {
$shipping_options[$key] = $settings['name'][$key] . " " . $settings['size'][$key] . " - $" . $settings['metro_manila_price'][$key];
}

Multidimensional Array - Pulling Data

New to PHP and after spending hours researching on here, nothing seems to be exactly what I need. I have a multi dimensional array that I'm looking to pull data and COUNT from. FOR Instance:
array (
'loyola' => NULL,
'gold_coast' => NULL,
'lincolnpark' =>
array (
0 => 'Building 1',
1 => 'Building 2',
2 => 'Building 3',
3 => 'Building 4'
),
'lakeview' =>
array (
0 => 'Building 1',
1 => 'Building 2',
2 => 'Building 3'
),
)
I'm looking to essentially create a table that lists all the buildings and in the next column the number of times that building appears.
This what I've gotten thus far, but it only displays all buildings.
$buildings = unserialize($row['buildings']);
$lincolnpark = $buildings['lincolnpark'];
$loyola= $buildings['loyola'];
$gold_coast = $buildings['gold_coast'];
$lakeview = $buildings['lakeview'];
foreach ($lakeview as $value)
{
echo $value;
}
}
Try the code below. It will navigate recursively into the array and will print the qtd each build appear.
<?php
$arr = array (
'loyola' => NULL,
'gold_coast' => NULL,
'lincolnpark' =>
array (
0 => 'Building 1',
1 => 'Building 2',
2 => 'Building 3',
3 => 'Building 4'
),
'lakeview' =>
array (
0 => 'Building 1',
1 => 'Building 2',
2 => 'Building 3'
),
);
$ret = array();
countBuildings($arr);
foreach($ret as $key=>$value){
echo "Building: $key ==> qtd : $value <br>";
}
function countBuildings($arr = array()){
global $ret;
foreach($arr as $value){
if(is_array($value)){
countBuildings($value);
}else{
if($value != NULL){
if(isset($ret[$value])){
$ret[$value] += 1;
}else{
$ret[$value] = 1;
}
}
}
}
}
Do it in two passes: one for counting building occurrences in a separate array, and another for output.

Categories