Loops into a multidimensional array with PHP - php

I have this array in PHP:
[data] => Array
(
[BOO_item_quantity] => Array
(
[0] => 1
[1] => 6
)
[BOO_item_id] => Array
(
[0] => 18
[1] => 13
)
[BOO_item_price] => Array
(
[0] => 3
[1] => 0
)
)
How is it possible to loop into this to get something like this please ?
Quantity = 1 - Item_Id = 18 - Price = 3
Quantity = 6 - Item_Id = 13 - Price = 0
Thanks.

You can use a foreach statement to loop over the elements the first sub-array:
$data = array(
'BOO_item_quantity' => array(1,6),
'BOO_item_id' => array(18,13),
'BOO_item_price' =>array(3,0)
);
foreach($data['BOO_item_quantity'] as $index=>$value) {
print 'Quantity = '.$value.' - Item_Id = '.$data['BOO_item_id'][$index].' - Price = '.$data['BOO_item_price'][$index].'<br />';
}
See it in action at phpfiddle.

Related

PHP - Array does not turn into two-dimensional array

I need to make my array better.
I am getting data from database and i have milestones and milestone_parts. i want two-dimensional array. I need data of milestones in the first dimension and milestone_parts in the second dimension.
With this code:
$query = "
SELECT
a.id AS `milestone_id`,
a.titel AS `milestone_titel`,
a.client AS `client`,
a.verkocht_id AS `milestone_verkocht_id`,
b.id AS `milestonefase_id`,
b.titel AS `milestonefase_titel`,
b.milestone_id AS `milestonefase_milestone_id`,
b.omschrijving AS `milestonefase_omschrijving`
FROM `milestones` a
INNER JOIN `milestone_parts` b ON a.id=b.milestone_id
WHERE a.verkocht_id = '99'
";
$result= $db->query($dbh, $query);
while ($row = $db->fetchassoc($result))
{
$stone = array($row['milestone_verkocht_id'], $row['milestone_id'], $row['milestone_titel'], $row['client']);
$fase = array($row['milestonefase_milestone_id'],$row['milestonefase_id'],$row['milestonefase_titel']);
$stone[] = $fase;
echo '<pre>'; print_r($stone); echo '</pre>';
}
I get this as result
Array
(
[0] => 99
[1] => 6
[2] => string
[3] => string
[4] => Array
(
[0] => 6
[1] => 10
[2] => string
)
)
Array
(
[0] => 99
[1] => 6
[2] => string
[3] => string
[4] => Array
(
[0] => 6
[1] => 11
[2] => string
)
)
but I need (with names) this:
Array
(
[milestone_verkocht_id] => 99 // This is project id
[milestone_id] => 6
[milestone_title] => string
[client] => string
[10] => Array
(
[milestonefase_milestone_id] => 6
[milestonefase_id] => 10
[milestone_title] => string
)
[11] => Array
(
[milestonefase_milestone_id] => 6
[milestonefase_id] => 11
[milestone_title] => string
)
[12] => Array
(
[milestonefase_milestone_id] => 6
[milestonefase_id] => 12
[milestone_title] => string
)
)
Can you help me or do you have a solution? Help me please!
you can cycle each field returned by the query, checking the field name and making new arrays
$stones = array();
while ($row = $db->fetchassoc($result)) {
$fase = array();
$stone = array('milestones' => array());
foreach ($row as $k => $v) {
if (strpos($k, 'milestonefase_') === 0) {
$fase[$k] = $v;
} else {
$stone[$k] = $v;
}
}
if(!isset($stones[$stone['milestone_id']])) {
$stones[$stone['milestone_id']] = $stone;
}
$stones[$stone['milestone_id']]['milestones'][$fase['milestonefase_id']] = $fase;
}
echo '<pre>'.print_r($stones, true).'</pre>';
Edit
made some changes in order to match the request. Now we use $stones to store the information we already have on a milestone, adding to it the different "$fase" returned from the query
Probably a more clean way is to retrieve all the information with two different queries one for milestones and the other for the fases
Edit2
Added a sub-array for the milestone fases

Average result of multidimensional array in PHP

This is a question for all the array specialists out there. I have an multi dimension array with a result as number (can be 0,1 or 2) and need the average for each grouped by parent.
In the example below the calculation would be:
subentry1_sub1 = 2 + 2 = 4 (4/2=2)
subentry1_sub2 = 1 + 1 = 2 (2/2=1)
So what I try to archive in PHP is the following result:
subentry1_sub1 average = 2
subentry1_sub2 average = 1
...
I already tried some solutions from similar questions. But with all the recursive functions I didn't managed to get it aggregated by the last child name (e.g. subentry1_sub1).
Any ideas?
EDIT:
subentry1_sub1 is 2 + 2 because its two times in the array
[entry1] => [subentry1] => [subentry1_sub1] => result
[entry2] => [subentry1] => [subentry1_sub1] => result
Array
(
[entry1] => Array
(
[subentry1] => Array
(
[subentry1_sub1] => Array
(
[value] => abc
[result] => 2
)
[subentry1_sub2] => Array
(
[value] => abc
[result] => 1
)
)
[subentry2] => Array
(
[subentry2_sub1] => Array
(
[value] => abc
[result] => 1
)
[subentry2_sub2] => Array
(
[value] => abc
[result] => 1
)
)
)
[entry2] => Array
(
[subentry1] => Array
(
[subentry1_sub1] => Array
(
[value] => abc
[result] => 2
)
[subentry1_sub2] => Array
(
[value] => abc
[result] => 1
)
)
[subentry2] => Array
(
[subentry2_sub1] => Array
(
[value] => abc
[result] => 1
)
[subentry2_sub2] => Array
(
[value] => abc
[result] => 1
)
)
)
)
Try this code. In this i have created a new array $sum which will add result value of same subentry childs with same key and another array $count which will count the number of times each key repeats
<?php
$data = array('entry1'=>array(
'subentry1'=>
array(
'subentry1_sub1'=>array('value'=>'abc','result'=>2),
'subentry1_sub2'=>array('value'=>'abc','result'=>1)
),
'subentry2'=>
array(
'subentry2_sub1'=>array('value'=>'abc','result'=>1),
'subentry2_sub2'=>array('value'=>'abc','result'=>1)
)
),
'entry2'=>array(
'subentry1'=>
array(
'subentry1_sub1'=>array('value'=>'abc','result'=>2),
'subentry1_sub2'=>array('value'=>'abc','result'=>1)
),
'subentry2'=>
array(
'subentry2_sub1'=>array('value'=>'abc','result'=>1),
'subentry2_sub2'=>array('value'=>'abc','result'=>1)
)
)
);
$sum = array();
$repeat = array();
foreach($data as $input){
foreach($input as $array){
foreach($array as $key=>$value){
if(array_key_exists($key,$sum)){
$repeat[$key] = $repeat[$key]+1;
$sum[$key] = $sum[$key] + $value['result'];
}else{
$repeat[$key] = 1;
$sum[$key] = $value['result'];
}}}}
echo "<pre>";
print_r($sum);
print_r($repeat);
foreach($sum as $key=>$value){
echo $key. ' Average = '. $value/$repeat[$key]."</br>";
}
Output
Array
(
[subentry1_sub1] => 4
[subentry1_sub2] => 2
[subentry2_sub1] => 2
[subentry2_sub2] => 2
)
Array
(
[subentry1_sub1] => 2
[subentry1_sub2] => 2
[subentry2_sub1] => 2
[subentry2_sub2] => 2
)
subentry1_sub1 Average = 2
subentry1_sub2 Average = 1
subentry2_sub1 Average = 1
subentry2_sub2 Average = 1
You can easily calculate avg now
Note : As you mentioned you are counting occurence of subentry1_sub1 etc so i did the same so it will also count whether key result exists or not
I know this is an old thread but im pretty sure there is a much easier way of doing this for anyone who is interested:
If you know the result will always be a number:
foreach($my_array as $entry_name => $entry_data)
{
foreach($entry_data as $sub_name => $sub_data)
{
$sub_results = array_column($sub_data, 'result');
$averages[$entry_name][$sub_name] = array_sum($sub_results)/count($sub_results);
}
}
If its possible the result could be NULL or empty, this will check it and return 'N/A' if there is no valid data to calculate an average from:
foreach($my_array as $entry_name => $entry_data)
{
foreach($entry_data as $sub_name => $sub_data)
{
$sub_results = array_filter(array_column($sub_data, 'result'));
$averages[$entry_name][$sub_name] = (count($sub_results) > 0 ? array_sum($sub_results)/count($sub_results) : 'N/A');
}
}
both of these solutions will give you an averages array that will output the average per subentry per entry.
Try this like,
<?php
$data=array('entry1'=>array(
'subentry1'=>
array(
'subentry1_sub1'=>array('value'=>'abc','result'=>3),
'subentry1_sub2'=>array('value'=>'abc','result'=>3)
),
'subentry2'=>
array(
'subentry2_sub1'=>array('value'=>'abc','result'=>2),
'subentry2_sub2'=>array('value'=>'abc','result'=>8)
)
),
'entry2'=>array(
'subentry1'=>
array(
'subentry1_sub1'=>array('value'=>'abc','result'=>6),
'subentry1_sub2'=>array('value'=>'abc','result'=>6)
),
'subentry2'=>
array(
'subentry2_sub1'=>array('value'=>'abc','result'=>10),
'subentry2_sub2'=>array('value'=>'abc','result'=>12)
)
)
);
foreach($data as $k=>$v){
echo "----------------$k---------------------\n";
if(is_array($v)){
foreach($v as $a=>$b){
if(is_array($b)){
echo $a.' average = ';
$c=array_keys($b);// now get *_sub*
$v1=isset($b[$c[0]]['result']) ? $b[$c[0]]['result'] : '';
$v2=isset($b[$c[1]]['result']) ? $b[$c[1]]['result'] : '';
echo ($v1+$v2)/2;
echo "\n";
}
}
}
}
Online Demo
In the meantime I found a simple working solution myself:
foreach ($data as $level2) {
foreach ($level2 as $level3) {
foreach ($level3 as $keyp => $level4) {
foreach ($level4 as $key => $value) {
if($key == 'result') $stats[$keyp] += $value;
}
}
}
}
With that you get the total for every key in an new array $stats.
But be sure to checkout the solution from user1234, too. It's working great and already includes the calculation of the average.
https://stackoverflow.com/a/39292593/2466703

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

Sum Multi Dimensional array if the sub key is exists

I have this array which has more then 100 results but some of these has same sub array key. I would like to sum array element which has same key which is [/xyx/888350] in this example. However, I want to keep the format as it is which is two dimensional.
Array
(
[0] => Array
(
[/xyx/888350] => /xyx/888350
[visitors] => 1
[pageviews] => 2
[uniquepageviews] => 1
)
[1] => Array
(
[/xyx/888350] => /xyx/888350
[visitors] => 1
[pageviews] => 3
[uniquepageviews] => 1
)
[2] => Array
(
[/xyx/888350] => /xyx/888350
[visitors] => 1
[pageviews] => 2
[uniquepageviews] => 1
)
[3] => Array
(
[/xyx/102254] => /xyx/102254
[visitors] => 1
[pageviews] => 2
[uniquepageviews] => 1
)
)
I am expecting out put something like below:
Array
(
[0] => Array
(
[/xyx/888350] => /xyx/888350
[visitors] => 2
[pageviews] => 7
[uniquepageviews] => 2
)
[1] => Array
(
[/xyx/102254] => /xyx/102254
[visitors] => 1
[pageviews] => 3
[uniquepageviews] => 1
)
)
Thanks in advance.
Loop the array, and store the results in a temporary array, by using the first value as a key:
$input = /*your example data here*/;
$result = array();
foreach($input as $data){
$keys = array_keys($data);
$key = $keys[0]; //get the first key of the array a.k.a '/xyx/888350'
if(isset($result[$key])){
//sum the values if we have this key
$result[$key]['visitors'] += $data['visitors'];
$result[$key]['pageviews'] += $data['pageviews'];
$result[$key]['uniquepageviews'] += $data['uniquepageviews'];
}else{
$result[$key] = $data;
}
}
//drop the extra keys and return a indexed array with the summed values
return array_values($result);
$results=$service->data_ga->get("");
$stats = array();
for ($i=0; $i < count($stats_results=$results->getRows()) ; $i++)
{
$stats[]=array(
'path'=>$stats_results[$i][1],
'visitors'=>$stats[$i]['visitors'] + $stats_results[$i][2],
'pageviews'=>$stats[$i]['visitors'] + $stats_results[$i][3],
'uniquepageviews'=>$stats[$i]['visitors'] + $stats_results[$i][4]
);
}
$result = array();
foreach($stats as $data){
$keys = array_keys($data);
$key = $keys[0]; //get the first key of the array a.k.a '/xyx/888350'
if(isset($result[$key]))
{
//sum the values if we have this key
$result[$key]['visitors'] += $data['visitors'];
$result[$key]['pageviews'] += $data['pageviews'];
$result[$key]['uniquepageviews'] += $data['uniquepageviews'];
}else{
$result[$key] = $data;
}
}
echo "<pre>";
print_r($result);
Output:
Array
(
[path] => Array
(
[path] => /path/888350
[visitors] => 3
[pageviews] => 7
[uniquepageviews] => 3
)
)
Thanks both of you. As time goes on I will also answer questions other people have. I have just started my career. Thank you guys :)

Filling php array that has missing values

I've a series of arrays with values that goes from 1 to 5. Almost every array has missing values, some even dont have any values. My objective is to fill the missing values with 0. All those arrays are stored into a multidimensional array.
My array looks like:
Array
(
[1] => Array
(
[0] => 1
[1] => 2
[2] => 3
)
[2] => Array
(
[0] => 1
[1] => 5
)
[3] => Array
(
[0] => (this array has no values)
)
[4] => Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
)
etc...
)
How it should be:
Array
(
[1] => Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 0
[4] => 0
)
[2] => Array
(
[0] => 1
[1] => 0
[2] => 0
[3] => 0
[4] => 5
)
[3] => Array
(
[0] => 0
[1] => 0
[2] => 0
[3] => 0
[4] => 0
)
[4] => Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
)
etc...
)
Any help would be appriciated!
For each of your subarrays loop through the numbers 1 to 5, and if that value exists set its key to be one less than its value:
$newarray = array();
foreach($arr as $key => $subarr) {
for ($i = 1; $i <= 5; $i++) {
if (in_array($i, $subarr)) $newarray[$key][$i - 1] = $i;
else $newarray[$key][$i - 1] = 0;
}
}
Where $newarray is your output and $arr is your input array.
You may want to note that PHP does not truly do multidimensional arrays. It only allows you to relate 2 flat arrays together which is not true multidimensionality.
This does not work and will produce results described above.
$menu[1] = "My Training"; //not $menu[1][0]
$menu[1][1] = "To Do List";
$menu[1][2] = "Catalog";
$menu[1][3] = "Self-Report";
$menu[1][4] = "Completions";
$menu[2] = "Manager";
$menu[2][1] = "Direct Reports";
$menu[2][2] = "Incompletes";
$menu[2][3] = "Completions";
$menu[3] = "Instructor";
$menu[3][1] = "My Classes";
$menu[3][2] = "Printables";
$menu[3][3] = "Qualifications";
This does work.
$menu[1] = "My Training"; //not $menu[1][0]
$submenu[1][1] = "To Do List";
$submenu[1][2] = "Catalog";
$submenu[1][3] = "Self-Report";
$submenu[1][4] = "Completions";
$menu[2] = "Manager";
$submenu[2][1] = "Direct Reports";
$submenu[2][2] = "Incompletes";
$submenu[2][3] = "Completions";
$menu[3] = "Instructor";
$submenu[3][1] = "My Classes";
$submenu[3][2] = "Printables";
$submenu[3][3] = "Qualifications";
$submenu is only related to $menu through the first key number as there are no first dimension values to $submenu.
Something like this (array_pad() won't do the trick). $myArray is your source array. Completed array is returned in $result:
$result = array();
foreach( $myArray as $subKey=>$subArray ) {
for( $i=0; $i<5; $i++ ) {
if( isset( $subArray[$i] )) {
$result[$subKey][$i] = $subArray[$i];
} else {
$result[$subKey][$i] = 0;
}
}
}
Note, we do copy of the array. You cannot fill array in-place.
It's been many years since I wrote any PHP but something like this might do the trick I guess?
for($i = 0; $i < 5; $i++)
{
if(empty($myArray[$i])
{
$myArray[$i] = 0;
}
}

Categories