Array driving me loop(y) - php

Pardon the pun in my title (heh) but this is seriously driving me nuts!
This is my code:
for ($i=0;$i < $a;$i++){
$total = (array)$orders -> Total -> Line[$i];
echo '<pre>';
print_r($total);
echo '</pre>';
}
...It outputs the following:
Array
(
[#attributes] => Array
(
[type] => Subtotal
[name] => Subtotal
)
[0] => 299.99
)
Array
(
[#attributes] => Array
(
[type] => Shipping
[name] => Shipping
)
[0] => 13.36
)
Array
(
[#attributes] => Array
(
[type] => Tax
[name] => Tax
)
[0] => 0.00
)
Array
(
[#attributes] => Array
(
[type] => GiftCertificate
[name] => Gift certificate discount (117943:#CAC7HXPXFUNNJ3MTGC:63.35 117372:#DK9T9TMTCTCTUWF9GC:250.00)
)
[0] => -313.35
)
Array
(
[#attributes] => Array
(
[type] => Total
[name] => Total
)
[0] => 0.00
)
My question is: how do I save each dollar amount [0] into a respective variable named according to the array['type']?

Rather than a variable (which could be done with variable variables), I recommend putting them into an array $prices, keyed by the type attributes.
$prices = array();
for ($i=0;$i < $a;$i++){
$total = (array)$orders -> Total -> Line[$i];
echo '<pre>';
print_r($total);
echo '</pre>';
// Append the price to an array using its type attribute as the
// new array key
$prices[$total['#attributes']['type']] = $total[0];
}
Untested, of course, but I believe it will do the job.

$var[] = array('type' => $total['#attributes']['type'], 'amount' => $total[0])

Something like this maybe?
$total_amount_by_type = array();
for ($i=0;$i < $a;$i++){
$total = (array)$orders -> Total -> Line[$i];
$total_amount_by_type[$total->type] = $total[0]
}

Are you looking for something like this:
for ($i=0;$i < $a;$i++){
$total = (array)$orders -> Total -> Line[$i];
// will create variables $Tax, $GiftCertificate etc
${$total['#attributes']['type']} = $total[0];
echo '<pre>';
print_r($total);
echo '</pre>';
}

Related

Merge array with same value in same key php

I have this code:
$order = wc_get_order( 988613 );
$product_array = array();
$daty = array();
$counter = 1;
foreach ($order->get_items() as $item_key => $item ){
$daty_dostaw = $item->get_meta('Daty dostaw');
$product_id = $item->get_product_id();
$daty_dostaw_explode = explode(',',$daty_dostaw);
$daty[$counter]['product_id'] = $product_id;
foreach($daty_dostaw_explode as $key => $data){
$daty[$counter]['data'][] = $data;
}
$counter++;
}
When I print it it shows me this
Array
(
[1] => Array
(
[product_id] => 988012
[data] => Array
(
[0] => 13-08-2022
[1] => 25-08-2022
[2] => 30-08-2022
)
)
[2] => Array
(
[product_id] => 988087
[data] => Array
(
[0] => 25-08-2022
[1] => 31-08-2022
[2] => 30-09-2022
)
)
)
I want to combine an array that have the same dates to display like this:
Array
( [1] => Array
(
[product_id] => array(988012, 988087)
[data] => Array
(
[0] => 25-08-2022
)
)
[2] => Array
(
[product_id] => 988012
[data] => Array
(
[0] => 13-08-2022
[1] => 30-08-2022
)
)
[3] => Array
(
[product_id] => 988087
[data] => Array
(
[0] => 31-08-2022
[1] => 30-09-2022
)
)
)
I want to merge the array those with the same dates. I don't know how to explain it exactly, above I showed what I would like to achieve. I have already written thousands of lines of code using foreach and have not been able to achieve this :(
Basically you want to convert product_id into an array if there are multiple products with the same date. I would search for such matches, create the merges, remove the elements from the individual occurrence or even the individual occurrence if it gets emptied. An example would be this:
$cachedDates = []; //Here we will store the dates we have gone through so far
foreach ($product_array as $key => $product) {
foreach ($product_array[$key]["data"] => $date) {
if (!in_array($date, $cachedDates)) {
//Creating a cache entry for this date
$cachedDates[$date] = ["keys" => [], "values" => []];
}
//Adding the key and product to the date's cache
$cachedDates[$date]["keys"][]= $key;
$cachedDates[$date]["values"][]= $product["product_id"];
}
}
//Adding the new items to $product_array and cleaning up items that become redundant
foreach ($cachedDates as $date => $entry) {
//We only merge items that have a not-unique date
if (count($entry["values"]) > 0) {
//adding a new item with the correct values and the date
$product_array[]= [
"product_id" => $entry["values"],
"data" => $date
];
//Cleanup
for ($index = 0; $index < count($entry["keys"]); $index++) {
//We remove the date from the data entry after finding its index
$removeIndex = array_search($date, $product_array[$entry["keys"][$index]]["data"]);
unset($product_array[$entry["keys"][$index]]["data"][$removeIndex]);
//If the data array is empty, then the whole product was already merged into some other item(s)
if (!count($product_array[$entry["keys"][$index]]["data"])) {
unset($product_array[$entry["keys"][$index]]);
}
}
}
}
The code above was untested, if you find issues with it and errors, then provide the appropriate PHP input instead of its print, even a json_encode result is good-enough

Sum array on key - possible or is the array not structured in a good way?

Have built the following array based on an accounting file and want to create sums from the [trans] subarray for all accounts based on the amount. Looked into array_column but have a feeling the array is not built correctly or in an efficient way for this? Any thoughts/suggestions much appreciated.
//Clarification
Hi! Many thanks. I was probably a bit unclear. For the total population of [trans] I want to sum the amount where the account is the same. So the array above would generate:
[1930] = -150.47-431.63
[5912] = 150.47
etc
[#VER] => Array
(
[A1] => Array
(
[verdatum] => 20150107
[vertext] => GOOGLE
[trans] => Array
(
[0] => Array
(
[account] => 1930
[amount] => -150.47
)
[1] => Array
(
[account] => 5912
[amount] => 150.47
)
[2] => Array
(
[account] => 2645
[amount] => 37.62
)
[3] => Array
(
[account] => 2614
[amount] => -37.62
)
)
)
[A2] => Array
(
[verdatum] => 20150118
[vertext] => Post
[trans] => Array
(
[0] => Array
(
[account] => 1930
[amount] => -431.63
)
[1] => Array
(
[account] => 5710
[amount] => 345.30
)
[2] => Array
(
[account] => 2641
[amount] => 86.33
)
)
)
)
Its simply a foreach loop to acheive your expected sum of amount
$temp = array();
$new = array();
foreach($arr as $key=>$value){
foreach($value["trans"] as $key2=>$value2){
if(in_array($value2["account"], $temp)){
$new[$value2["account"]] += $value2["amount"];
}else {
$new[$value2["account"]] = $value2["amount"];
$temp[] = $value2["account"];
}
}
}
print_r($new);
Live demo : https://eval.in/857342
Output will be
Array
(
[1930] => -582.1
[5912] => 150.47
[2645] => 37.62
[2614] => -37.62
[5710] => 345.3
[2641] => 86.33
)
$grand_total = 0;
array_walk($my_array['#VER'],function (&$ver) use (&$grand_total){
$ver['total_amount'] = 0;
foreach($ver['trans'] as $trans){
$ver['total_amount'] += $trans['amount'];
}
$grand_total += $ver['total_amount'];
});
So, simply loop through your "VER" then loop again on each trans. As simple as that. I've used both array_walk and foreach techniques, mainly to show you the two ways. You could prefer use two foreach, or two array_walk, it would work.
This script adds to a $grand_total variable, and also store the total of all transactions into each VER entry.
Modified:
$grand_total = 0;
array_walk($urarr['#VER'],function (&$ver) use (&$grand_total){
foreach($ver['trans'] as $trans){
if ($trans['amount'] < 0){
$neg += abs($trans['amount']);
}else{
$pos += abs($trans['amount']);
}
}
$diff = ($pos < $neg) ? "-".($neg - $pos) : ($pos - $neg);
$grand_total += $diff;
});
print $grand_total;

Multiply two arrays values based on the values on the other values

From the following array I am trying to multiple the quantity and the price on the condition that itemType is Zo.
(
[customer] => 4
[itemNo] => Array
(
[0] => 1
[1] => 2
)
[itemName] => Array
(
[0] => Type A
[1] => Type B
)
[itemType] => Array
(
[0] => Zo
[1] => Ram
)
[quantity] => Array
(
[0] => 2
[1] => 3
)
[price] => Array
(
[0] => 500
[1] => 2000
)
)
Here is what I have tried so far but with no success.
$lq = 0;
$total =0;
for ($i=0;$i<count($_REQUEST['price']);$i++) {
if(in_array("Ram", $_REQUEST['itemType'])){
$total += $_REQUEST['price'][$i] * $_REQUEST['quantity'][$i];
}else{
$lq += $_REQUEST['quantity'][$i];
}
}
echo ($total).'<br>';
echo ($lq);
My expected output is:
$total = 1000;//Quantity x Price
$lq = 3//Quantity only
You're not checking itemType of the same item that you're adding to the total. You're just checking whether any of the items have that itemType. You're also looking for Ram, not Zo.
if ($_REQUEST['itemType'][$i] == 'Zo') {
$total += $_REQUEST['price'][$i] * $_REQUEST['quantity'][$i];
} else {
$lq += $_REQUEST['quantity'][$i];
}
Try:
$data = $_REQUEST;
$key = array_search('Zo',$data['itemType']);
$total = $data['quantity'][$key] * $data['price'][$key];//Zo price*qty
$lq = array_sum($data['quantity']) - $data['quantity'][$key];//non-Zo qty
Live demo

How to parse JSON Array with different keys on the same level

I have Array and i need to get summ of quantity * price. But the array keys on the third level is different.
I use this PHP code but i only can take price & quantity for first item ['506-p1-8_p2-_p3-']
$quantity = $elements['1af7e792-bcff-4a6c-9bdb-dd5023b0251a']['items']['506-p1-8_p2-_p3-'][quantity];
$price = $elements['1af7e792-bcff-4a6c-9bdb-dd5023b0251a']['items']['506-p1-8_p2-_p3-'][price];
$summ = $price*$quantity;
How to parse all levels to get Summ = (price * quantity)
Thank to all who can help me
Array
(
[1af7e792-bcff-4a6c-9bdb-dd5023b0251a] => Array
(
[is_advance] => 1
[items] => Array
(
[506-p1-8_p2-_p3-] => Array
(
[hash] => 506-p1-8_p2-_p3-
[sku] => 501
[itemId] => 506
[quantity] => 6
[price] => 80.75
[currency] => UAH
[priceDesc] =>
[priceParams] => Array
(
[u0420u0430u0437u043cu0435u0440] => 8
)
[name] => qwerty
)
[498-p1-6_p2-_p3-] => Array
(
[hash] => 498-p1-6_p2-_p3-
[sku] => 498
[itemId] => 498
[quantity] => 5
[price] => 500
[currency] => UAH
[priceDesc] =>
[priceParams] => Array
(
[u0420u0430u0437u043cu0435u0440] => 6
)
[name] => qwerty
)
)
)
)
It's hard to tell how the array is generated in the first place. So just going off of the code you've posted, this should sum up the total for every item contained in the array.
$items = $elements['1af7e792-bcff-4a6c-9bdb-dd5023b0251a']['items'];
$sum = 0;
foreach($items as $item) {
$sum += $item['quantity'] * $item['price'];
}
In the sense of flexibility, you want your code as portable as possible. I assume your id isn't always going to be 1af7e792-bcff-4a6c-9bdb-dd5023b0251a, so you'll want to loop through the data that is returned.I don't know how you get the data, that's up to you.
So something like this, should gather the data you require and create an array:
$d = array();
foreach ($data as $id => $item) {
foreach ($item as $key => $values) {
$d[$id][$key]['sum'] = $values['price'] * $values['quantity'];
}
}
print_r($d);
Note: The above code is untested

How to print out Multi-Dimensional Arrays in php

Consider the array is:
Array
(
[Page-1] => Array
(
[0] => Array
(
[0] => Cat-1
[1] => Item-1
)
)
[Page-2] => Array
(
[0] => Array
(
[0] => Cat-2
[1] => Item-2
)
[1] => Array
(
[0] => Cat-3
[1] => Item-3
)
[2] => Array
(
[0] => Cat-4
[1] => Item-4
)
)
[Page-3] => Array
(
[0] => Array
(
[0] => Cat-5
[1] => Item-5
)
)
[Page-4] => Array
(
[0] => Array
(
[0] => Cat-6
[1] => Item-6
)
)
[Page-5] => Array
(
[0] => Array
(
[0] => Cat-7
[1] => Item-7
)
[1] => Array
(
[0] => Cat-9
[1] => Item-9
)
)
[Page-6] => Array
(
[0] => Array
(
[0] => Cat-8
[1] => Item-8
)
)
)
Where, the first keys [Page-x] from array will be Main-Links in the navigation menu.
Some of the main links may have Sub-Links, some not.
Sub-links are the values of the key [0] of the 3rd sub-array.
And finally the URL for each and every link will be the value of key [1] of the 3rd sub-Array.
Only Pages that have more than one category will show its categories as sub-links
The navigation bar i would like to have:
1. Page-1
2. Page-2
Cat-2
Cat-3
Cat-4
3. Page-3
4. Page-4
5. Page-5
Cat-7
Cat-9
6. Page-6
the PHP code
$records = $p->main_links();
foreach ($records as $key => $value) {
$return[$value['page']][] = array($value['child'], $value['item']);
}
foreach ($return as $key2 => $value2) {
$count = 0;
/* Select a specific value within the Array */
$main_links = $value2[$count][1]; /* URL of the main Pages */
$count = count($return[$key2]);
if($count > 1) {
foreach ($value2 as $key3 => $value3)
{
$link_name = $value3[0]; /* Child Link Names */
$link_url = $value3[1]; /* URL of Child Links */
/* addedd htmlspecialchars() function to $variables that will be echoed into HTML. It provides some XSS protection */
$cat_link .= '<li>'.htmlspecialchars($link_name).'</li>';
}
$result .= '
<li '.htmlspecialchars($li_class).'><span>'.htmlspecialchars($key2).'</span>
<ul>
'.$cat_link.'
</ul>
</li>';
}else {
$result .= '
<li><span>'.htmlspecialchars($key2).'</span></li>';
}
}
Unfortunately i can't get it work... the output is not what i am expecting :(
current Output (wrong one):
1. Page-1
2. Page-2
Cat-2
Cat-3
Cat-4
3. Page-3
4. Page-4
5. Page-5
Cat-2
Cat-3
Cat-4
Cat-7
Cat-9
6. Page-6
Any help would be appreciated!
Your current code is close to working. This line will always produce a count of 1.
$count = count($value);
What you're looking for there, I believe, is:
$count = count($return[$key]);
I've found another way around which is way better than the one i was trying to do. This solved my case.
http://wizardinternetsolutions.com/articles/web-programming/single-query-dynamic-multi-level-menu
Thank you for your support!

Categories