For example I have a mysql_num_rows results of 4,8,15,16,23,42 in a query that is inside a while loop of another query. My question is how can I get the percentage per each result of mysql_num_rows inside my while loop? Example: 4,8,15,16,23,42. Total is 108. $sum = 108. Percentage of 4 = 4/$sum = 3.7%, 8 = 8/$sum = 7.4% and so on..
you can store all the values in an array and do the calcs after you have retrieved the data from the database
eg
$datastore = array();
$total = 0;
while(list($amount) = mysql_fetch_row($result)) {
$datastore[] = $amount;
$total += $amount;
}
foreach ($datastore as $amount) {
echo $amount," - ";
printf("%5.2f", $amount/$total);
echo "\r\n";
}
$values = array(4, 8, 15, ...);
$sum = array_sum($values);
foreach($values as $value) {
echo ($value / $sum) * 100;
}
CodePad.
So you are saying that you want the $sum before the individual results right? You could do a simple additional query to get the sum before you pull out the individual results. Use the SUM aggregate function. It is probably also possible to get the percentage in your SQL results. That would mean a slightly more complex query, but not an additional query.
Related
I'm trying to combine numbers in an array by adding them so that the max value can only by 30.
For example, this is my array:
array(10,30,10,10,15);
After combining the numbers in the array to items with a max value 30, the result should be:
array(30,30,15);
How to achieve this?
I'm trying to combine numbers in an array by adding them so that the
max value can only by 30
So, when you combine numbers, you can achieve the lowest possible set of values in your array and also make sure that max value remains 30 by:
First, sort them.
Second, keeping adding elements to sum till you are about to get a sum > 30.
Third, once an element can no longer be added to a sum, add the current sum in your array and make the current element as the new sum.
Code:
<?php
$arr = array(10,30,10,10,15);
sort($arr);
$res = [];
$curr_sum = 0;
foreach($arr as $each_value){
if($curr_sum + $each_value <= 30) $curr_sum += $each_value;
else{
$res[] = $curr_sum;
$curr_sum = $each_value;
}
}
$res[] = $curr_sum;
print_r($res);
Demo: https://3v4l.org/BYhuE
Update: If order of the numbers matters, seeing your current output, you could just use rsort() to show them in descending order.
rsort($res);
$total = array_sum(array(10,30,10,10,15)); //assign sum totals from orignal array
$maxValue = 30; //assign max value allowed in array
$numberOfWholeOccurancesOfMaxValue = floor($total/$maxValue);
$remainder = $total%$maxValue;
//build array
$i=0;
while ( $i < $numberOfWholeOccurancesOfMaxValue ){
$array[] = $maxValue;
$i++;
}
$array[] = $remainder;
print_r($array);
You can loop only once to get this,
$temp = array(10,30,10,10,15);
natsort($temp); // sorting to reduce hustle and complication
$result = [];
$i = 0;
$maxValue = 30;
foreach($temp as $v){
// checking sum is greater or value is greater or $v is greater than equal to
if(!empty($result[$i]) && (($result[$i]+$v) > $maxValue)){
$i++;
}
$result[$i] = (!empty($result[$i]) ? ($result[$i]+$v) : $v);
}
print_r($result);
Working demo.
I believe finding most space-optimized/compact result requires a nested loop. My advice resembles the firstFitDecreasing() function in this answer of mine except in this case the nested loops are accessing the same array. I've added a couple of simple conditions to prevent needless iterations.
rsort($array);
foreach ($array as $k1 => &$v1) {
if ($v1 >= $limit) {
continue;
}
foreach ($array as $k2 => $v2) {
if ($k1 !== $k2 && $v1 + $v2 <= $limit) {
$v1 += $v2;
unset($array[$k2]);
if ($v1 === $limit) {
continue 2;
}
}
}
}
rsort($array);
var_export($array);
By putting larger numbers before smaller numbers before processing AND by attempting to add multiple subsequent values to earlier values, having fewer total elements in the result is possible.
See my comparative demonstration.
I believe #Clint's answer is misinterpreting the task and is damaging the data by summing all values then distributing the max amounts in the result array.
With more challenging input data like $array = [10,30,5,10,5,13,14,15,10,5]; and $limit = 30;, my solution provides a more dense result versus #nice_dev's and #rahul's answers.
I have and foreach loop that outputs the totals I want to add when i echo the $val_tex it outputs in one number like "4911165" but if I echo it with a break tag it gives me the right values. It looks like
49
1
1
1
65
My question is how to get the sum of all the values which should equal "117"
$val_tex = array();
foreach ( $get_seller as $keys ) {
$val_tex = $keys['total'];
}
You have to add them together in the foreach loop - there's a simple way to do that $total += $keys['total']; It's just a simpler way of saying $total = $total + $keys['total'];
There are also other ways - $total = array_sum(array(1,2,3,4)); // == 10 for example. To get the sum from a single column, you get an array that only contains the values from the specific column first:
// an array of the values from that column
$arrayTotall = array_column($keys, 'total');
$total = array_sum($arrayTotals);
Your for each needs another variable to add them:
foreach ( $get_seller as $keys ) {
$val_tex = $keys['total'];
$sum = += $val_tex
//or...
$val_tex += $keys['total'];
//depending on how you want to us val_tex
}
The .= adds the value to previous value instead of overwriting it.
i want to calculate two operations with the help of loop. They are already working and providing result i need. But i want them to look more like coding. So if anybody can help them with the help of for in php
for($i=0;i<something;$i++){
$temp_calc = ;
}
here are two statements.
In first statement length of array is 9.
In second statement length of array is 12.
both statements to be solved in different for loop as they are totally different questions.
$temp_calc = 10*$temp_array[0]+9*$temp_array[1]+8*$temp_array[2]+7*$temp_array[3]+6*$temp_array[4]+5*$temp_array[5]+4*$temp_array[6]+3*$temp_array[7]+2*$temp_array[8];
$temp_calc = 1*$temp_array[0]+3*$temp_array[1]+1*$temp_array[2]+3*$temp_array[3]+1*$temp_array[4]+3*$temp_array[5]+1*$temp_array[6]+3*$temp_array[7]+1*$temp_array[8]+3*$temp_array[9]+1*$temp_array[10]+3*$temp_array[11];
Thanks in advance
It will be a little simpler to use a foreach loop rather than a for loop. If you specifically need to use a for loop because it is a requirement of an assignment, you can check the PHP documentation. There are some examples there of using a for loop to loop over an array. This is a common and basic control structure and it will be more valuable for you to really understand how to use it. The more important part is what goes on inside the loop. There are multiple ways to do this, but here are some basic examples.
First one:
// initialize multiplier and result outside the loop
$multiplier = 10;
$result = 0;
// loop over the values
foreach ($temp_array as $value) {
// add the value * multiplier to the result and decrement the multiplier
$result += $value * $multiplier--;
}
Second one
// initialize multiplier and result outside the loop
$multiplier = 1;
$result = 0;
// loop over the values
foreach ($temp_array as $value) {
// add the value * multiplier to the result
$result += $value * $multiplier;
// switch the multiplier to the alternating value
if ($multiplier == 1) {
$multiplier = 3;
} else {
$multiplier = 1;
}
// The switch can be done more simply using a ternary operator like this:
// $multiplier = $multiplier == 1 ? 3 : 1;
}
for both issues:
$temp_array = array(2,2,2,2,2,2,2,2,2);//sample
function calc_1($temp_array){//first
$total=0;
$count = count($temp_array)+1;
foreach($temp_array as $value){
$total += $count*$value;
$count-=1;
}
return $total;
}
function calc_2($temp_array){//second
$total=0;
foreach($temp_array as $k=>$value){
$total += ($k%2==0) ? 1*$value : 3*$value;//when is even or odd
}
return $total;
}
var_dump(calc_1($temp_array));//resp1
var_dump(calc_2($temp_array));//resp2
If your array is called $myArray, then:
/*Since I can't know what the sequence of the values are that you
are multiplying, and because you might need other sequences in the
future, a function was developed that chooses which sequence you
want to multiply.*/
function findSomeValues($arraySize)
{
switch ($arraySize) {
case 9:
{
$someValues = array(10,9,8,7,4,5,4,3,2);
}
break;
case 12:
{
$someValues = array(1,3,1,3,1,3,1,3,1,3,1,3);
}
break;
default:
$someValues = array();
}
return $someValues;
}
/*This following function then finds how big your array is, looks
for a sequence stored in the findSomeValues function. If a sequence
exist for that array size (in this case if you have an array either
9 or 12 elements long), the result will be calculated and echoed. If
the sequence was not found, an error message would be echoed.*/
function multiplyValues($myArray) {
$result = 0;
$arraySize = count($myArray);//obtaining array size
$someValues = findSomeValues($arraySize);//obtaining sequence to multiply with
if (count($someValues)>0)
{
for($i=0;i<$arraySize;$i++){
$result += $myArray[i]*$someValues[i];
}
echo "result = ".$result."<br>";//result message
}
else
{
echo "you are missing some values<br>";//error message
}
}
Let me know if that worked for you.
Alternative:
If you prefer something a bit simpler:
//this array holds the sequences you have saved:
$sequenceArray = array(
9 => array(10,9,8,7,4,5,4,3,2),
12 => array(1,3,1,3,1,3,1,3,1,3,1,3)
);
//this function does the multiplication:
function multiplyValues($myArray)
{
$arraySize = count($myArray);
for($i=0;i<$arraySize;$i++){
$result += $myArray[i]*$sequenceArray[i];
}
echo "result = ".$result."<br>";//result message
}
For your result
$temp_calc = 10*$temp_array[0]+9*$temp_array[1]+8*$temp_array[2]+7*$temp_array[3]+6*$temp_array[4]+5*$temp_array[5]+4*$temp_array[6]+3*$temp_array[7]+2*$temp_array[8];
You should have for loop as following. It will run the loop till 8th index of your temp_array and multiply each index value with $i and sum up in a variable $temp_calc_1.
<?php
$temp_calc_1 = 0;
for($i=0;$i<9;$i++){
$temp_calc_1 = $temp_calc_1 + ( 10-$i)*$temp_array[$i] ;
}
For your second result
$temp_calc = 1*$temp_array[0]+3*$temp_array[1]+1*$temp_array[2]+3*$temp_array[3]+1*$temp_array[4]+3*$temp_array[5]+1*$temp_array[6]+3*$temp_array[7]+1*$temp_array[8]+3*$temp_array[9]+1*$temp_array[10]+3*$temp_array[11];
The above should be converted to the following loop, this will run loop till your 12th index of temparrayand do the calculation. This time it will multiply each index value of temparray by either 1 and 3. So first time it will multiply with 1 and next time with 3 and so on
//
$temp_calc_2 = 0;
for($i=0;$i<12;$i++){
$j = $i%2?3:1;
$temp_calc_2 = $temp_calc_2 + $j*$temp_array[$i] ;
}
?>
This is driving me nuts! I need to fill up and HTML table with values that I pulled out from a DB.
The HTML table has 100 one td for each value.
I have an array that I populate doing this:
$x = 1;
$ArrayA = array();
for ($x = 1; $x <= 100; $x++) {
$ArrayA[$x] = 0;
}
So now I have an array with 100 values, right?
Then I query my DB, and get the result that I "want"
(select num from table1)
6 rows with the following values:
1,3,14,50,100.
Then I insert the values from my query into the $ArrayA that I populated before with one hundred 0's
$x = 1;
while ($row = mysql_fetch_array($result))
{
extract($row);
$ArrayA[$x] = "$num";
$x++;
}
Now $ArrayA has this:
1,3,14,17,100,0,0,0,0,0,0,0,0,0,0,0,0.....
And my goal is to replace with a 0 where I should have a "next" number, hard to explain..
I need this result:
1,0,3,0,0,0,0,0,0,0,0,0,0,14,0,0,17,0....
I tried to use PHP array_splice, but it did not work.
I tried with some if statements but my logic and programing experience is not that good.
Any suggestions?
Thanks
If i understand this right, you want to add a zero after every element returned by your query? Right? If so, why not add a zero right after you add an element into the array?
$x = 1; while ($row = mysql_fetch_array($result)) {
extract($row);
$ArrayA[$x] = "$num";
$x++;
$ArrayA[$x] = "0"; //adds zero after every $num insert
}
Maybe you can clarify if this isn't what you're asking...
$match_rows = mysql_fetch_array($result);
$rows = range(1,100);
foreach( $rows as $row){
echo '<td>';
if( in_array($row, $match_rows) ){
echo $row;
}else{
echo 0;
}
echo '</td>' . PHP_EOL;
}
Sorry, that is untested - it could be shorter or neater, but like that possibly illustrates another way of achieving what you want.
I think this is what you want for your second code block:
while ($row = mysql_fetch_array($result))
{
extract($row);
if($num > 0 && $ <= 100 )
{
$ArrayA[$num] = "$num";
}
}
If your DB values are 3, 10, 15, 22, 100, you'd end up with 0,0,3,0,0,0,0,0,0,10,0,0,0,0,15, etc etc.
I've a $max which is essentially a two dimensional array.
Each element in $max is eithor 1 or 0,
can be denoted by $max[$x][$y], where $x is an integer within 0~WIDTH,similar for $y
My purpose is to find rows and columns in the $maxthat sums up greater than a CONSTANT, and get the average distance between rows/columns that qualify.
Anyone has a good solution ?
I have not tested this, but it should work for summing up the columns and rows:
//Map columns and rows into their respective values
//Note that we preserve the col/row indexes
$rowval = array();
$colval = array();
foreach($max as $k1 => $row) {
$rowval[$k1] = array_sum($row);
foreach($row as $k2 => $col) {
if(!isset($colval[$k2])) {
$colval[$k2] = 0;
}
$colval[$k2] += $col;
}
}
//Define filter function
function is_over($val) {
return $val > CONSTANT;
}
//Filter out the cols/rows from their respective arrays
//Keys will be preserved by array_filter
$foundcols = array_filter($colval, 'is_over');
$foundrows = array_filter($rowval, 'is_over');
You still have to calculate the average distance though.