PHP for loop with array and array slice functions - php

As part of an expense data analyze, I am trying to find out top 3 expense categories for each month.Right now I have 3 months data : Array $month0,$month1,$month3.
Right now I am using below code and its working fine
$month0 = array("Bank"=>$Bank[0], "CreditCard"=>$CreditCard[0], "Loan"=>$Loan[0],"Household"=>$Household[0],"Utilities"=>$Utilities[0]);
$month1 = array("Bank"=>$Bank[1], "CreditCard"=>$CreditCard[1], "Loan"=>$Loan[1],"Household"=>$Household[1],"Utilities"=>$Utilities[1]);
$month2 = array("Bank"=>$Bank[2], "CreditCard"=>$CreditCard[2], "Loan"=>$Loan[2],"Household"=>$Household[2],"Utilities"=>$Utilities[2]);
arsort($month0 );
arsort($month1 );
arsort($month2 );
$top3month0 = array_slice($month0, 0, 3);
$top3month1 = array_slice($month1, 0, 3);
$top3month2 = array_slice($month2, 0, 3);
foreach ($top3month0 as $category => $amount){
$cat_top3month0[] = $category;
$amt_top3month0[] = $amount;
}
foreach ($top3month1 as $category => $amount){
$cat_top3month1[] = $category;
$amt_top3month1[] = $amount;
}
foreach ($top3month2 as $category => $amount){
$cat_top3month2[] = $category;
$amt_top3month2[] = $amount;
}
//For Month0
echo "Top 1 category is ".$cat_top3month0[0]." and amount: ".$amt_top3month0[0];
echo "Top 2 category is ".$cat_top3month0[1]." and amount: ".$amt_top3month0[1];
echo "Top 3 category is ".$cat_top3month0[2]." and amount: ".$amt_top3month0[2];
//For Month1
echo "Top 1 category is ".$cat_top3month1[0]." and amount: ".$amt_top3month1[0];
echo "Top 2 category is ".$cat_top3month1[1]." and amount: ".$amt_top3month1[1];
echo "Top 3 category is ".$cat_top3month1[2]." and amount: ".$amt_top3month1[2];
//For Month3
echo "Top 1 category is ".$cat_top3month2[0]." and amount: ".$amt_top3month2[0];
echo "Top 2 category is ".$cat_top3month2[1]." and amount: ".$amt_top3month2[1];
echo "Top 3 category is ".$cat_top3month2[2]." and amount: ".$amt_top3month2[2];
I am trying to use for loop here to reduce the length of the code. I changed above code like below using for loop
for ($i = 0; $i<3; $i++){
$month[i] = array("Bank"=>$Bank[i], "CreditCard"=>$CreditCard[i], "Loan"=>$Loan[i],"Household"=>$Household[i],"Utilities"=>$Utilities[i]);
arsort($month[i] );
$top3month[i] = array_slice($month[i], 0, 3);
foreach ($top3month[i] as $category => $amount){
$cat_top3month[i][] = $category;
$amt_top3month[i][] = $amount;
}
}
//For Month0
/echo "Top 1 category is ".$cat_top3month0[0]." and amount: ".$amt_top3month0[0];
/echo "Top 2 category is ".$cat_top3month0[1]." and amount: ".$amt_top3month0[1];
/echo "Top 3 category is ".$cat_top3month0[2]." and amount: ".$amt_top3month0[2];
//For Month1
echo "Top 1 category is ".$cat_top3month1[0]." and amount: ".$amt_top3month1[0];
echo "Top 2 category is ".$cat_top3month1[1]." and amount: ".$amt_top3month1[1];
echo "Top 3 category is ".$cat_top3month1[2]." and amount: ".$amt_top3month1[2];
//For Month3
echo "Top 1 category is ".$cat_top3month2[0]." and amount: ".$amt_top3month2[0];
echo "Top 2 category is ".$cat_top3month2[1]." and amount: ".$amt_top3month2[1];
echo "Top 3 category is ".$cat_top3month2[2]." and amount: ".$amt_top3month2[2];
But above code is not working. When looking at the debug log I see below error
PHP Warning: Use of undefined constant i - assumed 'i' (this will throw an Error in a future version of PHP)
against line
$month[i] = array("Bank"=>$Bank[i], "CreditCard"=>$CreditCard[i], "Loan"=>$Loan[i],"Household"=>$Household[i],"Utilities"=>$Utilities[i]);
I am new to PHP and still learning. Can someone please tell me the issue with code ? or suggest a better approach to this ?
Update:
Updated the code to correct i to $i
for ($i = 0; $i<3; $i++){
$month[$i] = array("Bank"=>$Bank[$i], "CreditCard"=>$CreditCard[$i], "Loan"=>$Loan[$i],"Household"=>$Household[$i],"Utilities"=>$Utilities[$i]);
arsort($month[$i] );
$top3month[$i] = array_slice($month[$i], 0, 3);
foreach ($top3month[$i] as $category => $amount){
$cat_top3month[$i][] = $category;
$amt_top3month[$i][] = $amount;
}
}
//For Month0
echo "Top 1 category is ".$cat_top3month0[0]." and amount: ".$amt_top3month0[0];
echo "Top 2 category is ".$cat_top3month0[1]." and amount: ".$amt_top3month0[1];
echo "Top 3 category is ".$cat_top3month0[2]." and amount: ".$amt_top3month0[2];
//For Month1
echo "Top 1 category is ".$cat_top3month1[0]." and amount: ".$amt_top3month1[0];
echo "Top 2 category is ".$cat_top3month1[1]." and amount: ".$amt_top3month1[1];
echo "Top 3 category is ".$cat_top3month1[2]." and amount: ".$amt_top3month1[2];
//For Month3
echo "Top 1 category is ".$cat_top3month2[0]." and amount: ".$amt_top3month2[0];
echo "Top 2 category is ".$cat_top3month2[1]." and amount: ".$amt_top3month2[1];
echo "Top 3 category is ".$cat_top3month2[2]." and amount: ".$amt_top3month2[2];
Now I have below errors:
PHP Notice: Array to string conversion in
against line :
$month[$i] = array("Bank"=>$Bank[$i], "CreditCard"=>$CreditCard[$i], "Loan"=>$Loan[$i],"Household"=>$Household[$i],"Utilities"=>$Utilities[$i]);
and
PHP Fatal error: Uncaught Error: Only variables can be passed by reference in
against arsort($month[$i] );

Related

Merging two product star ratings with foreach in Woocommerce

There may be a better way to state the question, but I'm workin' with what I know.
On Woocommerce I'm trying to get the _wc_rating_count for each star (1-5), but also for two products; then I want to combine theme; e.g., I am merging the reviews of two products on one page, in one graph.
I am doing that this way:
$product_id = array( 2146, 2166 );
$ratings = array(5, 4, 3, 2, 1);
foreach ($product_id as $pid) :
$product = wc_get_product($pid);
foreach ($ratings as $rating) :
$rating_count = $product->get_rating_count($rating);
$percentage = ($rating_count / $count) * 100 . "%";
//echo $rating_count . '<br/>';
endforeach;
endforeach;
The problem is, I'm getting an array of 10 items (2 products x 5 star ratings( 5,4,3,2,1), and I need those values merged.
11
1
0
0
2
8
0
0
0
1
Where I need it to be
19
1
0
0
3
Do you know how I may get two arrays out of the embedded foreachs and merge them based on the $ratings array?
Thanks for your help :)
So here is what do you like to achieve:
$product_ids = array( 2146, 2166 );
$ratings = array(5, 4, 3, 2, 1);
$rate_countings = array();
foreach ($product_ids as $pid){
$product = wc_get_product($pid);
foreach ($ratings as $rating){
$rating_count = $product->get_rating_count($rating);
//$percentage = ($rating_count / $count) * 100 . "%";
if( !isset($rate_countings[$rating]) ){
$rate_countings[$rating] = 0;
}
$rate_countings[$rating] += $rating_count;
}
}
var_dump($rate_countings);

Using php arrays to query database

I am trying to query mysql db using values passed in an array. The problem is the first element produces two results. Here is my code and results.
$common = array_intersect($ingredients, $ingredients2);
unset($common['1']);
$unique = array_unique($common);
echo "The common array is:";
print_r(array_count_values($common));
echo "<br> The unique array is :";
print_r($unique);
echo "<br>";
echo extract($unique)."<br>";
$i = 0;
$sum = 0;
foreach (array_count_values($common) as $key => $value) {
$keys = "$key";
$value = "$value";
echo "$keys : ";
echo "$value<br>";
$i++;
$sql = mysql_query("SELECT * FROM `ingredients` WHERE `name` = '$keys'") or die(mysql_error());
while ($row = mysql_fetch_array($sql)) {
$price = $row['price'];
echo "The price is : $price<br>";
$total_price = $value*$price;
echo "The total price for $keys is : $total_price<br>";
$sum+= $total_price;
}
}
echo "The sum of the prices is $sum";
Here is what I get:
The common array is:Array ( [test] => 3 [ugali] => 2 [mboga] => 2 [0] => 1 )
The unique array is :Array ( [0] => test [2] => ugali [4] => mboga [8] => 0 )
0
test : 3
The price is : 100
The total price for test is : 300
The price is : 100
The total price for test is : 300
ugali : 2
The price is : 100
The total price for ugali is : 200
mboga : 2
The price is : 4
The total price for mboga is : 8
0 : 1
The sum of the prices is 808
I got the answer to this. I removed the while loop and it worked instead of
while ($row = mysql_fetch_array($sql)) {}
I have
$row = mysql_fetch_array($sql);
That solved the problem.

Woocommerc if two products in cart make a set price

I am trying to add discounts to the total price of the cart when the quantity of the cart is in multiples of 2; I've have some code in place that only allows one quantity of each product and I plan on having 9 products.
Right now the prices are $17/product; if the user adds two products, the total should be $30, and that should reflect at every multiple of 2 quantity (meaning with 3 products, the price is $47, but at 4, it's $60).
Below is my code. For some reason when I have one product in the cart it sets the total to $30.
function custom_price_function( $total, $cart ) {
//if( $cart->cart_contents_count = 2 && $cart->cart_contents_count >= 80 )
if( $cart->cart_contents_count = 2 )
$total = 30;
return $total;
}
add_filter( 'woocommerce_calculated_total', 'custom_price_function', 10, 2 );
Something like this should work:
function calculate_total($total, $cart) {
if($cart->cart_contents_count == 1){
return $total;
}
$to_discount = 0;
for($x = 0; $x <= $cart->cart_contents_count; $x ++){
if($x % 2 === 0){
$to_discount += 2;
}
if($cart->cart_contents_count == $x && $x % 2 === 0){
$to_discount += 2;
}
}
return $new_price - $to_discount;;
}
add_filter( 'woocommerce_calculated_total', 'calculate_total', 10, 2 );
what we do is calculate base on the total of items in the cart. you can extend this to be more dynamic. but it does what you need for now
Simple test:
for($x = 1; $x < 10; $x++ ){
echo calculate_total(17 * $x, $x) . "\n";
}
Output:
17
30
47
62
79
94
111
126
143

Group matched array values

Program:
while($i<=$row) {
echo $arr[$i][1].$arr[$i][4]
}
Output
Product Code Qty
KC_DRINK_TASTY_CASE 1
KC_DRINK_TASTY_CASE 1
KC_DRINK_TASTY_CASE 1
KC_DRINK_TASTY_CASE 1
KC_SUNGLASSES_BK 1
KC_SUNGLASSES_BK 1
KC_SUNGLASSES_BE 1
KC_SUNGLASSES_BE 1
KC_SUNGLASSES_OE 1
KC_SUNGLASSES_OE 1
KC_SUNGLASSES_RD 1
KC_SUNGLASSES_RD 1
KC_SUNGLASSES_WE 1
KC_SUNGLASSES_WE 1
I want it to output
KC_DRINK_TASTY_CASE 4
KC_SUNGLASSES 10
so that it group product code excluding last underscore and sum their quantity
If $arr looks something like this:
$arr = array(
array('{something}', 'KC_DRINK_TASTY_CASE', '{something}', '{something}', 1),
array('{something}', 'KC_SUNGLASSES_BK', '{something}', '{something}', 1),
// ...
);
Then you can get the output what you what like this:
// we'll store counts here
$result = array();
foreach ($arr as $row) {
$product = $row[1];
$qty = $row[4];
// figure out where the last underscore is and chop off everything that follows it
// this is VERY brittle. If the product ends up with a name like _SOMEKEY you'll end
// up with an empty key. Not good. Probably not a huge issue, but buyer beware
$_product = substr($product, 0, strrpos($product, '_'));
if (isset($result[$_product])) {
$result[$_product] += $qty; // we already started counting
} else {
$result[$_product] = $qty; // not started counting this product yet, start it
}
}
// now print your result:
foreach ($result as $id => $qty) {
echo $id, "\t", $qty, PHP_EOL;
}

Ordering multidimensional associative arrays

I want to order this array by price AND keep my keys without them being changed.
Here is what I have been working with.
<?php
$a = array(
1=>array('price'=>9.25,'timestamp_added'=>1301945848,'name'=>'pencils'),
4=>array('price'=>19.15,'timestamp_added'=>1299267448,'name'=>'crayon box'),
15=>array('price'=>4.25,'timestamp_added'=>1299785848,'name'=>'markers'),
2=> array('price'=>4.28,'timestamp_added'=>1299785848,'name'=>'eraser'),
44=>array('price'=>13.99,'timestamp_added'=>1299872248,'name'=>'trapper'),
32=>array('price'=>9.25,'timestamp_added'=>1299872248,'name'=>'notebook'),
14=>array('price'=>13.99,'timestamp_added'=>1301945848,'name'=>'sharpener'),
5=>array('price'=>15.01,'timestamp_added'=>1299872248,'name'=>'calculator')
);
function printList( $a ){
echo "<br />";
foreach ($a as $key => $value){
echo "<br /> Product ID $key Price: " . $value['price'] . " Timestamp: " . $value['timestamp_added'] . " Name: " . $value['name'];
}
}
printList( $a );
$price = array();
foreach ($a as $key => $row)
{
$price[$key] = $row['price'];
}
array_multisort($price, SORT_ASC, $a);
printList( $a );
?>
Output:
Product ID 1 Price: 9.25 Timestamp: 1301945848 Name: pencils
Product ID 4 Price: 19.15 Timestamp: 1299267448 Name: crayon box
Product ID 15 Price: 4.25 Timestamp: 1299785848 Name: markers
Product ID 2 Price: 4.28 Timestamp: 1299785848 Name: eraser
Product ID 44 Price: 13.99 Timestamp: 1299872248 Name: trapper
Product ID 32 Price: 9.25 Timestamp: 1299872248 Name: notebook
Product ID 14 Price: 13.99 Timestamp: 1301945848 Name: sharpener
Product ID 5 Price: 15.01 Timestamp: 1299872248 Name: calculator
Product ID 0 Price: 4.25 Timestamp: 1299785848 Name: markers
Product ID 1 Price: 4.28 Timestamp: 1299785848 Name: eraser
Product ID 2 Price: 9.25 Timestamp: 1299872248 Name: notebook
Product ID 3 Price: 9.25 Timestamp: 1301945848 Name: pencils
Product ID 4 Price: 13.99 Timestamp: 1299872248 Name: trapper
Product ID 5 Price: 13.99 Timestamp: 1301945848 Name: sharpener
Product ID 6 Price: 15.01 Timestamp: 1299872248 Name: calculator
Product ID 7 Price: 19.15 Timestamp: 1299267448 Name: crayon box
It sorts the array, but the keys are changed. How can I keep the keys labeled the way they were?
You can use uasort function
$a = array(
1=>array('price'=>9.25,'timestamp_added'=>1301945848,'name'=>'pencils'),
4=>array('price'=>19.15,'timestamp_added'=>1299267448,'name'=>'crayon box'),
15=>array('price'=>4.25,'timestamp_added'=>1299785848,'name'=>'markers'),
2=> array('price'=>4.28,'timestamp_added'=>1299785848,'name'=>'eraser'),
44=>array('price'=>13.99,'timestamp_added'=>1299872248,'name'=>'trapper'),
32=>array('price'=>9.25,'timestamp_added'=>1299872248,'name'=>'notebook'),
14=>array('price'=>13.99,'timestamp_added'=>1301945848,'name'=>'sharpener'),
5=>array('price'=>15.01,'timestamp_added'=>1299872248,'name'=>'calculator')
);
function printList( $a ){
echo "<br />";
foreach ($a as $key => $value){
echo "<br /> Product ID $key Price: " . $value['price'] . " Timestamp: " . $value['timestamp_added'] . " Name: " . $value['name'];
}
}
printList( $a );
function sbyprice($a, $b)
{
return ($a['price'] >= $b['price']) ? 1 : 0;
}
uasort($a , "sbyprice");
printList( $a );
?>
Output :
Product ID 1 Price: 9.25 Timestamp: 1301945848 Name: pencils
Product ID 4 Price: 19.15 Timestamp: 1299267448 Name: crayon box
Product ID 15 Price: 4.25 Timestamp: 1299785848 Name: markers
Product ID 2 Price: 4.28 Timestamp: 1299785848 Name: eraser
Product ID 44 Price: 13.99 Timestamp: 1299872248 Name: trapper
Product ID 32 Price: 9.25 Timestamp: 1299872248 Name: notebook
Product ID 14 Price: 13.99 Timestamp: 1301945848 Name: sharpener
Product ID 5 Price: 15.01 Timestamp: 1299872248 Name: calculator
Product ID 15 Price: 4.25 Timestamp: 1299785848 Name: markers
Product ID 2 Price: 4.28 Timestamp: 1299785848 Name: eraser
Product ID 32 Price: 9.25 Timestamp: 1299872248 Name: notebook
Product ID 1 Price: 9.25 Timestamp: 1301945848 Name: pencils
Product ID 44 Price: 13.99 Timestamp: 1299872248 Name: trapper
Product ID 14 Price: 13.99 Timestamp: 1301945848 Name: sharpener
Product ID 5 Price: 15.01 Timestamp: 1299872248 Name: calculator
Product ID 4 Price: 19.15 Timestamp: 1299267448 Name: crayon box
uasort is the thing for you
for example:
<?php
function my_sort($a,$b)
{
if ($a==$b) return 0;
return ($a<$b)?-1:1;
}
$arr=array("a"=>4,"b"=>2,"c"=>8,d=>"6");
uasort($arr,"my_sort");
?>
Same as others, but using inline function, which may be better:
uasort ( $array , function($a, $b) {
return $a['price'] >= $b['price'] ? 1 : 0 ;
});
usort will solve your issue.Please reffer this link.

Categories