PHP: how to make a sum inside a "for each" cycle? - php

I've made a foreach loop that print some variables found in an xml file:
foreach ($xml->result->rowset->row as $row)
{
echo $row["price"] . " " . $row["product"] . "</br>";
}
I would like to get the sum of all the "prices" shown. How can i do?

Just have a variable add up those values as you iterate:
$total = 0; // start with zero
foreach ($xml->result->rowset->row as $row)
{
$total += $row["price"]; // add price to total
echo $row["price"] . " " . $row["product"] . "</br>";
}
echo $total; // echo out total amount

Store the count in a variable:
$total = 0;
foreach ($xml->result->rowset->row as $row) {
echo $row["price"] . " " . $row["product"] . "</br>";
$total += $row['price']; // assumed row_price is some integer
}
echo $total;

Simply add it to a new variable:
$sum = 0;
foreach ($xml->result->rowset->row as $row) {
echo $row["price"] . " " . $row["product"] . "<br />";
$sum += $row["price"];
}
echo $sum . "<br />";

$sum = 0;
foreach ($xml->result->rowset->row as $row)
{
echo $row["price"] . " " . $row["product"] . "</br>";
$sum += $row["price"] ;
}
echo $sum ;
isnt that simple ?

$sum=0;
foreach ($xml->result->rowset->row as $row)
{
echo $row["price"] . " " . $row["product"] . "</br>";
$sum +=$row["price"];
}
echo $sum;
just try this code!!

Related

php add random array not repeating most recent 5

I'm trying to re-write this code so that it goes with the columns that are going to be user-defined. With this, my challenge consists of
a) Needs to select random starting item from array
b) Select the next random color from the original array that is not equivalent to the most recent items selected based the number: $intNotesColumn + 1
I was thinking a do-while statement nested inside another was appropriate for this but am unsure how to go about this. Here is my code so far:
$metroUIcolors = array( "#A30061", "#8200CC", "008987", "#A05000", "#B85A93", "#C07807", "#E51400", "#297A29" );
$metroUIcolorsLength = count($metroUIcolors);
$intNotesColumn = 3; // This will be user-defined later
// Now I query the SQL database to get my base-code
if ($result->num_rows > 0) {
// output data of each row
echo '<table border=0 valign=top>'
. '<tr>'
. '<td colspan=' . $intNotesColumn . '>' . '<h1>header</h1>' . '</td>'
. '</tr>'
. '<tr>';
$counterRank = 1;
while($row = $result->fetch_assoc()) {
echo "<td bgcolor=" . $metroUIcolors[rand(0, $metroUIcolorsLength - 1)]. ">"
. "<h2>" . $row["username"] . '</h2><br />'
. "<p class='notes'>" . $row["notes"] . "</p>"
. "<p class='footnotes'>"
. "<br />Last Reset: " . $row["lastReset"]
. '<br />Last Update: ' . $row['lastUpdate']
. '<br />SessionID: ' . $row["sessionID"]
. "<br />Counter = " . $counterRank . "</td>". '</p>';
if ($counterRank % $intNotesColumn == 0)
{
echo '</tr><tr>';
}
$counterRank++;
}
echo '</tr></table>';
} else{
echo "No Notes Found in databases";
}
Then, why don't you do it order picking one color at a time. You could use shuffle() so that there will be a different starting color everytime.
<?php
$counterRank = 1;
// shuffle the array
shuffle($metroUIcolors);
while($row = $result->fetch_assoc()) {
$rand_color = $counterRank % $metroUIcolorsLength;
echo "<td bgcolor=" . $metroUIcolors[$rand_color]. ">";
// everything else
$counterRank++;
}
?>
If you insist on doing the way you said, you may create an array $colorCount which has color codes as keys and count as values.
<?php
$counterRank = 1;
$colorCount = array_fill_keys($metroUIcolors, 0);
while($row = $result->fetch_assoc()) {
do {
$rand_color = $metroUIcolors[rand(0, $metroUIcolorsLength - 1)];
} while ($colorCount[$rand_color] > 5);
echo "<td bgcolor=" . $rand_color. ">";
// everything else
$counterRank++;
$colorCount[$rand_color] += 1;
}
?>

Applying array_map recursively (array_walk_recursive?)

I have an associative array that is I am creating from an ODBC query with the following code:
while ($row=odbc_fetch_array($oexec)) {
if(empty($group[$row['gmm']])) {
$group[$row['gmm']] = array();
}
if(empty($group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']])) {
$group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']] = array();
}
if(empty($group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']])) {
$group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']] = array();
}
if(empty($group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']])) {
$group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']] = array();
}
if(empty($group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']][$row['dept_subcatg_desc']])) {
$group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']][$row['dept_subcatg_desc']] = array();
}
$group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']][$row['dept_subcatg_desc']]['total_ty_yest_sales'] = $row['total_ty_yest_sales'];
$group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']][$row['dept_subcatg_desc']]['total_wo_dotcom_ty_yest_sales'] = $row['total_wo_dotcom_ty_yest_sales'];
$group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']][$row['dept_subcatg_desc']]['east_ty_yest_sales'] = $row['east_ty_yest_sales'];
$group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']][$row['dept_subcatg_desc']]['central_ty_yest_sales'] = $row['central_ty_yest_sales'];
$group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']][$row['dept_subcatg_desc']]['west_ty_yest_sales'] = $row['west_ty_yest_sales'];
$group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']][$row['dept_subcatg_desc']]['dotcom_ty_yest_sales'] = $row['dotcom_ty_yest_sales'];
}
This gives me an array where:
$myArray = Array(GMM => Array(acctg_dept_nbr => Array(dept_category_desc => Array(dept_subcatg_desc => Array(value1,value2,value3)))))
I want to sum the values at every level. So for every acctg_dept_nbr[dept_category_desc][dept_subcatg_desc] I want to sum value1,value2,value3. Same for the GMM level and down to the dept_subcatg_desc level. Summing the dept_subcatg_desc level wasn't a problem. I dug around and found how to sum the dept_category_desc level, but am having trouble applying that method recursively.
Here is the code that puts the values into a table:
foreach($group as $gmm => $acctg_dept_nbrs) {
echo "<tr class=\"header\">
<td>" . $gmm . "</td>\n";
foreach ($acctg_dept_nbrs as $acctg_dept_nbr => $dept_catg_grp_descs) {
echo "<tr class=\"header\">\n
<td style=\"padding-left: 1em;\">" . $acctg_dept_nbr . "</td>\n";
foreach($dept_catg_grp_descs as $dept_catg_grp_desc => $dept_category_descs) {
echo "<tr class=\"header\">\n
<td style=\"padding-left: 2em;\">" . $dept_catg_grp_desc . "</td>\n";
//echo "<td>" . array_sum(array_walk_recursive($dept_category_descs,function($item) {return $item['total_ty_yest_sales'];})) . "</td>";
foreach($dept_category_descs as $dept_category_desc => $dept_subcatg_descs) {
echo "<tr class=\"header\">\n
<td style=\"padding-left: 3em;\">" . $dept_category_desc . "</td>\n";
echo "<td>" . array_sum(array_map(function($item) {return $item['total_ty_yest_sales'];},$dept_subcatg_descs)) . "</td>";
echo "<td>" . array_sum(array_map(function($item) {return $item['east_ty_yest_sales'];},$dept_subcatg_descs)) . "</td>";
echo "<td>" . array_sum(array_map(function($item) {return $item['central_ty_yest_sales'];},$dept_subcatg_descs)) . "</td>";
echo "<td>" . array_sum(array_map(function($item) {return $item['west_ty_yest_sales'];},$dept_subcatg_descs)) . "</td>";
foreach($dept_subcatg_descs as $dept_subcatg_desc => $values) {
echo "<tr>\n
<td style=\"padding-left: 4em;\">" . $dept_subcatg_desc . "</td>\n";
$sum = $values['total_ty_yest_sales'];
echo "<td>".$sum."</td>";
$sum = $values['east_ty_yest_sales'];
echo "<td>".$sum."</td>";
$sum = $values['central_ty_yest_sales'];
echo "<td>".$sum."</td>";
$sum = $values['west_ty_yest_sales'];
echo "<td>".$sum."</td>";
}
}
}
}
}
The commented out line is the problem for me now. This:
array_sum(array_map(function($item) {return $item['west_ty_yest_sales'];},$dept_subcatg_descs))
works fine at that level, but not at the higher levels. I have also tried to tweak this function to no avail:
function array_map_recursive($callback, $array) {
foreach ($array as $key => $value) {
if (is_array($array[$key])) {
$array[$key] = array_map_recursive($callback, $array[$key]);
}
else {
$array[$key] = call_user_func($callback, $array[$key]);
}
}
return $array;
}
How can I make this work so that regardless of level it will dig down and sum the values for that portion of the array?
function array_map_recursive($callback, $array)
{
$func = function ($item) use (&$func, &$callback) {
return is_array($item) ? array_map($func, $item) : call_user_func($callback, $item);
};
return array_map($func, $array);
}
function array_map_recursive($callback, $array)
{
if(is_array($callback)){
foreach ($callback as $function){
$array = array_map_recursive($function, $array);
}
return $array;
}
$func = function ($item) use (&$func, &$callback) {
return is_array($item) ? array_map($func, $item) : call_user_func($callback, $item);
};
return array_map($func, $array);
}
This way you can call the function passing more functions.. ex:
$rowData = array_map_recursive(['utf8_decode', 'trim'], $rowData);
Or simple call just one:
$rowData = array_map_recursive('trim', $rowData);
It can be a little difficult if we add multiple arrays to the function. But with only one, there is no problem at all.
function array_map_recursive(&$arr, $fn) {
return array_map(function($item) use($fn){
return is_array($item) ? array_map_recursive($item, $fn) : $fn($item);
}, $arr);
}
$array = array_map_recursive($array, function($item){
//TODO logic here
});
filter_var can essentially be used to accomplish this
function array_map_recursive(callable $func, array $array) {
return filter_var($array, FILTER_CALLBACK, ['options' => $func]);
}
There is one big drawback...
The callback will receive the value as a string.
and the leafs can't be objects

displaying multidimensional array

How do you display the output of a 2 dimensional arrays
Here's the code:
I know how to display both of them separately doing.
foreach($Father as $value){
echo $value[0] . " " . $value[1] . "<br />";
}
foreach($Son as $value){
echo $value[0] . " " . $value[1] . "<br />";
}
try this - it assumes that each father has exactly 1 son though
$i = 0;
foreach($Father as $value){
echo $value[0] . " " . $value[1] . "<br />";
echo "-" . $Son[$i][0] . " " . $Son[$i][1] . "<br />";
$i += 1;
}

foreach in php iterates only through the first JSON

Please have a look at: http://codepad.org/uNlMsvwj for the json.
$json = json_decode($raw_json);
//print_r($json);
$count = count($json->response->results);
$i = 0;
foreach($json->response->results as $item){
echo($item->entries[$i]->displayname);echo "<br>";
echo($item->entries[$i]->location->street);echo " "; echo($item->entries[$i]->location->streetnumber);echo "<br>";
echo($item->entries[$i]->location->zipcode);echo " ";
echo($item->entries[$i]->location->city);echo "<br>";echo "<br>";
echo($item->entries[$i]->phonenumbers[0]->area);echo "/"; echo($item->entries[$i]->phonenumbers[0]->number);echo "<br>";
$i++;
}
The problem is that only the first elemet is printed. If i change $i manually with 1 i get the second.
I've been looking for 3 hours now and can't find a solution. Please forgive me if it is a beginner mistake.
Thanks
Update:
thank you all for your fast help
Did you mean to iterate over the results like so?
foreach($json->response->results as $item) {
for ($i = 0; $i < count($item->entries); $i++) {
echo($item->entries[$i]->displayname);echo "<br>";
echo($item->entries[$i]->location->street);echo " ";
echo($item->entries[$i]->location->streetnumber);echo "<br>";
echo($item->entries[$i]->location->zipcode);echo " ";
echo($item->entries[$i]->location->city);echo "<br>";echo "<br>";
echo($item->entries[$i]->phonenumbers[0]->area);echo "/";
echo($item->entries[$i]->phonenumbers[0]->number);echo "<br>";
}
}
Also, you can simplify your echo statements:
foreach($json->response->results as $item) {
for ($i = 0; $i < count($item->entries); $i++) {
echo $item->entries[$i]->displayname.'<br>';
echo $item->entries[$i]->location->street.' ';
echo $item->entries[$i]->location->streetnumber.'<br>';
echo $item->entries[$i]->location->zipcode.' ';
echo $item->entries[$i]->location->city.'<br><br>';
echo $item->entries[$i]->phonenumbers[0]->area.'/';
echo $item->entries[$i]->phonenumbers[0]->number.'<br>';
}
}
Try this one,it works I tested it:
foreach($json->response->results[0]->entries as $item){
echo($item->displayname);echo "<br>";
echo($item->location->street);echo " ";
echo($item->location->streetnumber);echo "<br>";
echo($item->location->zipcode);echo " ";
echo($item->location->city);echo "<br>";echo "<br>";
echo($item->phonenumbers[0]->area);echo "/"; echo($item->phonenumbers[0]->number);echo "<br>";
}
You should echo like this:
echo $item->entries[$i]->displayname . "<br>";
the . concatenates strings. Also echo doesn't use any ().
Change
foreach($json->response->results as $item){
to
foreach($json->response->results->entries as $item){
and these lines
echo($item->entries[$i]->displayname);echo "<br>";
to
echo $item->displayname . "<br>";
So your code will look like:
foreach($json->response->results->entries as $item){
echo "{$item->displayname}<br />";
echo "{$item->location->street} {$item->location->streetnumber}<br />";
echo "{$item->zipcode}<br />";
echo "{$item->location->city}<br /><br />";
echo "{$item->phonenumbers[0]->area}/{$item->phonenumbers[0]->number}<br />";
}
Try either for-loop instead of foreach:
$json = json_decode($raw_json);
//print_r($json);
$count = count($json->response->results);
foreach($json->response->results->entries as $item){
echo($item->displayname);echo "<br>";
echo($item->location->street);echo " ";
echo($item->location->streetnumber);echo "<br>";
echo($item->location->zipcode);echo " ";
echo($item->location->city);echo "<br>";echo "<br>";
echo($item->phonenumbers[0]->area);echo "/"; echo($item->phonenumbers[0]->number);echo "<br>";
}
...or include a for-loop inside the foreach:
$json = json_decode($raw_json);
//print_r($json);
$count = count($json->response->results);
foreach($json->response->results as $item){
for ($i = 0; $i < count($item->entries); $i++) {
echo($item->entries[$i]->displayname);echo "<br>";
echo($item->entries[$i]->location->street);echo " ";
echo($item->entries[$i]->location->streetnumber);echo "<br>";
echo($item->entries[$i]->location->zipcode);echo " ";
echo($item->entries[$i]->location->city);echo "<br>";echo "<br>";
echo($item->entries[$i]->phonenumbers[0]->area);echo "/";
echo($item->entries[$i]->phonenumbers[0]->number);echo "<br>";
}
}

Increment an array counter

In the loop below I want $value[0] to increment on each pass of the loop. So, if $count = 2 the loop will run twice and output $key . " " . $value[0] and $key . " " . $value[1].
Right now, my loop is outputting $key . " " . $value[0] twice. What did I do wrong?
$count = count($updates['positionTitle']);
for($i = 1; $i<=$count; $i++){
foreach($updates as $key => $value){
if(!is_array($value))
echo $key . " " . $value . "<br/>";
else
echo $key . " " . $value[0]++ . "<br/>";
}
}
You need to store what the current index is. I'm not actually sure what loop you were talking about though. I'm assuming it was the outer for loop. I still think this is broken but based on your comment this is what you want.
$count = count($updates['positionTitle']);
$idx = 0;
for($i = 1; $i<=$count; $i++){
foreach($updates as $key => $value){
if(!is_array($value))
echo $key . " " . $value . "<br/>";
else
echo $key . " " . $value[$idx] . "<br/>";
}
$idx++;
}
Change:
foreach($updates as $key => $value){
To:
foreach($updates as $key => &$value){

Categories