how can i show php array multiplying in loop
I have to show in the foreach so that I can add mysql
$data = [
[
"id" => "3202",
"total" => "5"
],[
"id" => "3190",
"total" => "2"
],[
"id" => "3199",
"total" => "5"
]
];
foreach($data as $v){
//$v["total"]*
//output = 5x2x5= 50
}
You can use array_column and array_product in this problem:
<?php
$data = [
['id' => '3202','total' => '5'],
['id' => '3190','total' => '2'],
['id' => '3199','total' => '5']
];
$total = array_column($data, 'total');
$product = array_product($total);
printf('The product of total: %s', $product);
PHP array functions online
<?php
$data = [
['id' => '3202','total' => '5'],
['id' => '3190','total' => '2'],
['id' => '3199','total' => '5']
];
$total = 1; // empty product
$output = [];
foreach($data as $v) {
$total *= $v['total'];
$output[] = $v['total'];
}
echo implode('x', $output) . '= ' . $total; // 5x2x5= 50
Might want to also add logic to check if the $data is empty first with count($data), then when the list is empty, output a message instead.
Related
I need to add new elemets to my array when a new category value is encountered. When a category value is encountered after the first time, its value1 and value2 values should be added to the first encounter's respective values.
Also, in the result array, I no longer wish to keep the category column. The category-grouping rows should use the category value as its name value.
Sample input:
$datas = [
[
'category' => 'Solution',
'name' => 'Name1',
'value1' => 20,
'value2' => 21
],
[
'category' => 'Solution',
'name' => 'Name2',
'value1' => 30,
'value2' => 31
],
[
'category' => 'Solution1',
'name' => 'Name3',
'value1' => 40,
'value2' => 41
]
];
Desired result:
[
['name' => 'Solution', 'value1' => 50, 'value2' => 52],
['name' => 'Name1', 'value1' => 20, 'value2' => 21],
['name' => 'Name2', 'value1' => 30, 'value2' => 31],
['name' => 'Solution1', 'value1' => 40, 'value2' => 41],
['name' => 'Name3', 'value1' => 40, 'value2' => 41]
]
I tried like this:
private function groupByProductSuperCategory($datas)
{
$return = [];
foreach ($datas as $data) {
$return[$data['category']][$data['name']] = array_sum(array_column('category', $data);
}
return $return;
}
The idea is to calculate first all sum values for by category, and after that just put values from name like another array. Have you an idea of how to do that?
From the posted array... To end in the desired array, there is some tiny fixes to do first. But I assumed it was due to typos while copying here...
So here is the array I started with:
$result = [
0 => [
"category" => 'Solution',
"name" => 'Name1',
"value1" => 20,
"value2" => 21
],
1 => [
"category" => 'Solution',
"name" => 'Name2',
"value1" => 30,
"value2" => 31
],
2 => [
"category" => 'Solution1',
"name" => 'Name3',
"value1" => 40,
"value2" => 41
]
];
Now, that re-organization of the data is a bit more complex than it looks... You need to perform several loops to:
Find distinct "category" names
Perform the summations for each
Add the sum item and the single items
So here is the code I ended with:
function groupByProductSuperCategory($datas){
$category = [];
$return = [];
// Find distinct categories
foreach ($datas as $data) {
if(!in_array($data["category"],$category)){
array_push($category,$data["category"]);
}
}
// For each distinct category, add the sum item and the single items
foreach ($category as $cat) {
// Get the sums
if(!in_array($cat,$return)){
$sum1 = 0;
$sum2 = 0;
foreach ($datas as $data) {
if($data["category"] == $cat){
$sum1 += $data["value1"];
$sum2 += $data["value2"];
}
}
}
// Push the sums in the return array
array_push($return,[
"name" => $cat,
"value1" => $sum1,
"value2" => $sum2,
]);
// Push the single elements
foreach ($datas as $data) {
if($cat == $data["category"]){
array_push($return,[
"name" => $data["name"],
"value1" => $data["value1"],
"value2" => $data["value2"],
]);
}
}
}
return $return;
}
Here is a PHPFiddle to try it out... Hit [F9] to run.
It is much more direct, efficient, and readable to implement a single loop and push reference variables into the result array to allow summing based on shared categories without keeping track of the actual indexes of the category rows.
Code: (Demo)
$result = [];
foreach ($array as $row) {
if (!isset($ref[$row['category']])) {
$ref[$row['category']] = [
'name' => $row['category'],
'value1' => 0,
'value2' => 0
];
$result[] = &$ref[$row['category']];
}
$ref[$row['category']]['value1'] += $row['value1'];
$ref[$row['category']]['value2'] += $row['value2'];
unset($row['category']);
$result[] = $row;
}
var_export($result);
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'];
I have an array as key => value pair such as:
$array = [ 10 => 'Windows', 12 => 'Keyboard', 15 => 'Monitor' ];
What I would like to achieve without using any foreach or loops the following:
$converted = [
0 => [ 'id' => 10, 'name' => 'Windows'],
1 => [ 'id' => 12, 'name' => 'Keyboard'],
2 => [ 'id' => 15, 'name' => 'Monitor']
];
Here they indices in new array doesn't matter. Any tips??
No foreach and no loop, but now there is a closure:
$result = array_map(function ($id, $name) {
return [
'id' => $id,
'name' => $name
];
}, array_keys($array), array_values($array));
Even if there was a PHP function that did this exactly, it would be using a loop internally.
function do_what_ghazanfar_mir_wants(array $array) {
return array_map(function ($id, $name) {
return [
'id' => $id,
'name' => $name
];
}, array_keys($array), array_values($array));
}
And the single liner is:
$result = do_what_ghazanfar_mir_wants($array);
And the foreach approach for comparison:
$res = [];
foreach ($array as $id => $name) {
$res[] = [ 'id' => $id, 'name' => $name ];
}
If you want to keep it really short then array_walk will do it in one line:
array_walk($array, function(&$value, $key) { $value = ['id' => $key, 'name' => $value]; });
See https://3v4l.org/OEohi
But I think a foreach loop is probably going to be a lot more readable.
Do it with array_map(), Just pass the keys array_keys($array) and values $array as the parameter of your array_map()
<?php
$array = [ 10 => 'Windows', 12 => 'Keyboard', 15 => 'Monitor' ];
function map_by_key($m, $n)
{
return(array('id' => $m, 'name'=>$n));
}
$output = array_map("map_by_key", array_keys($array),$array);
print '<pre>';
print_r($output);
print '</pre>';
?>
DEMO: https://3v4l.org/iTVSm
The question is simple, I want to create the array below dynamically, but the code I got now only outputs the last row. Is there anybody who knows what is wrong with my dynamically array creation?
$workingArray = [];
$workingArray =
[
0 =>
[
'id' => 1,
'name' => 'Name1',
],
1 =>
[
'id' => 2,
'name' => 'Name2',
]
];
echo json_encode($workingArray);
/* My not working array */
$i = 0;
$code = $_POST['code'];
$dynamicArray = [];
foreach ($Optionsclass->get_options() as $key => $value)
{
if ($value['id'] == $code)
{
$dynamicArray =
[
$i =>
[
'id' => $key,
'name' => $value['options']
]
];
$i++;
}
}
echo json_encode($dynamicArray);
You dont need to have the $i stuff that is adding another level to your array that you dont want.
$code = $_POST['code'];
$dynamicArray = [];
foreach ($Optionsclass->get_options() as $key => $value)
{
if ($value['id'] == $code)
{
$dynamicArray[] = ['id' => $key, 'name' => $value['options'];
}
}
echo json_encode($dynamicArray);
You are creating a new dynamic array at each iteration:
$dynamicArray =
[
$i =>
[
'id' => $key,
'name' => $value['options']
]
];
Instead, declare $dynamicArray = []; above the foreach, and then use:
array_push($dynamicArray, [ 'id' => $key, 'name' => $value['options']);
inside the array.
I want to avoid if it is possible foreach combined with if. I want to search the array, take out the matches and create new one base on result.
In this example I want to create separate arrays for each os -
$os1 = $array;
$os2 = $array...
Array looks like this:
$array = [
0 => [
'id' => 1,
'name' => 'name',
'os' => 1
],
1 => [
'id' => 2,
'name' => 'name',
'os' => 1
],
2 => [
'id' => 3,
'name' => 'name',
'os' => 2
],
3 => [
'id' => 3,
'name' => 'name',
'os' => 2
]
];
Use array_filter to reduce the input array to the expected result
$os = 1;
$data = array_filter($array, function($item) use ($os) {
return $item['os'] == $os;
});
The short one
$os1 = [];
$os2 = [];
$os3 = [];
foreach ($array as $item) {
${'os' . $item['os']}[] = array('id' => $item['id'], 'name' => $item[$name];
}
The better one
$os1 = [];
$os2 = [];
$os3 = [];
foreach ($array as $item) {
switch($item['os']) {
case 1:
$os1[] = array('id' => $item['id'], 'name' => $item[$name]);
break;
case 2:
$os2[] = array('id' => $item['id'], 'name' => $item[$name]);
break;
case 3:
$os3[] = array('id' => $item['id'], 'name' => $item[$name]);
break;
default:
throw new Exception('Unknown Os');
}
}
Also you maybe want to assign array($item['id'] => $item[$name]); instead of array('id' => $item['id'], 'name' => $item[$name]);
$os1 = [];
$os2 = [];
$os3 = [];
foreach ($array as $item) {
${'os' . $item['os']}[] = array($item['id'] => $item[$name]);
}