php find two array values in result multidimensional array - php

I am looking for last three month state wise data.I have all state code array and last three month array with the following values,
$stateArray = array("Nj","va","Ca","BS","TS");
$MonthArray =array("Nov 2016","Dec 2016","Jan 2017");
Below is my result array fetch from the database,
Array (
[0] => Array (
[month] => Nov 2016
[count] => 150
[state] => NJ
)
[1] => Array (
[month] => Nov 2016
[count] => 100
[state] => va
)
)
I want result like below,
Array(
[Nj] => Array(
[0] => Array(
[month] => Nov 2016
[count] => 150
)
[1] => Array(
[month] => Dec 2016
[count] => 0
)
[2] => Array(
[month] => jan 2017
[count] => 0
)
)
[Ca] => Array(
[0] => Array(
[month] => Nov 2016
[count] => 0
)
[1] => Array(
[month] => Dec 2016
[count] => 0
)
[2] => Array(
[month] => jan 2017
[count] => 0
)
)
[va] => Array(
[0] => Array(
[month] => Nov 2016
[count] => 100
)
[1] => Array(
[month] => Dec 2016
[count] => 0
)
[2] => Array(
[month] => jan 2017
[count] => 0
)
)
)
and so on for all states.
I am trying to array array_search() and in_array() functions for each but it is not working.What I would like to accomplish to loop each state wise array.Below I am trying for looping,
foreach ( $result_array as $val ) {
$month = array_search ( $val ['month'], $monthArray );
$state = array_search ( $val ['state'], $stateArray );
if ($val ['count'] == '' || $val ['count'] == 'NULL') {
$countValue = 0;
} else {
$countValue = $val ['count'];
}
$final_array [] = $countValue;
}

Take a look at this simple example:
<?php
$input = [
[
'month' => "Nov 2016",
'count' => "150",
'state' => "NJ"
],
[
'month' => "Nov 2016",
'count' => "100",
'state' => "va"
],
[
'month' => "Dec 2016",
'count' => "270",
'state' => "NJ"
],
];
$output = [];
foreach (["Nj", "va", "Ca", "BS", "TS"] as $state) {
$output[strtoupper($state)] = [];
};
array_walk($input, function($entry) use (&$output) {
$output[strtoupper($entry['state'])][] = [
'month' => $entry['month'],
'count' => $entry['count']
];
});
print_r($output);
The result of the above code is:
Array
(
[NJ] => Array
(
[0] => Array
(
[month] => Nov 2016
[count] => 150
)
[1] => Array
(
[month] => Dec 2016
[count] => 270
)
)
[VA] => Array
(
[0] => Array
(
[month] => Nov 2016
[count] => 100
)
)
[CA] => Array
(
)
[BS] => Array
(
)
[TS] => Array
(
)
)
This appears to be the exact output structure you ask for.

$stateArray = array("Nj","va","Ca","BS","TS");
$MonthArray =array("Nov 2016","Dec 2016","Jan 2017");
$fromDB = Array (
Array (
'month' => 'Nov 2016',
'count' => 150,
'state' => 'NJ'
),
Array (
'month' => 'Nov 2016',
'count' => 100,
'state' => 'va'
)
);
$info = array();
foreach ($fromDB as $row){
$info[strtoupper($row['state'])][$row['month']] = $row['count'];
}
$result = array();
foreach ($stateArray as $state){
foreach ($MonthArray as $month){
$result[$state][]=array('month'=>$month, 'count'=>isset($info[strtoupper($state)][$month])?$info[strtoupper($state)][$month]:0);
}
}
print_r($result);
will output
Array
(
[Nj] => Array
(
[0] => Array
(
[month] => Nov 2016
[count] => 150
)
[1] => Array
(
[month] => Dec 2016
[count] => 0
)
[2] => Array
(
[month] => Jan 2017
[count] => 0
)
)
[va] => Array
(
[0] => Array
(
[month] => Nov 2016
[count] => 100
)
[1] => Array
(
[month] => Dec 2016
[count] => 0
)
[2] => Array
(
[month] => Jan 2017
[count] => 0
)
)
[Ca] => Array
(
[0] => Array
(
[month] => Nov 2016
[count] => 0
)
[1] => Array
(
[month] => Dec 2016
[count] => 0
)
[2] => Array
(
[month] => Jan 2017
[count] => 0
)
)
[BS] => Array
(
[0] => Array
(
[month] => Nov 2016
[count] => 0
)
[1] => Array
(
[month] => Dec 2016
[count] => 0
)
[2] => Array
(
[month] => Jan 2017
[count] => 0
)
)
[TS] => Array
(
[0] => Array
(
[month] => Nov 2016
[count] => 0
)
[1] => Array
(
[month] => Dec 2016
[count] => 0
)
[2] => Array
(
[month] => Jan 2017
[count] => 0
)
)
)

Related

Way to compare array key & replace value if found (PHP)

Hello i am trying to make an php application, but i am having some trouble with arrays
Actually,
I m trying to compare array key & if found replace its value & merge whole array into one.
For example
Array ONE-
Array
(
[0] => Array
(
[label] => July 20 2020
[y] => 3
)
[1] => Array
(
[label] => July 18 2020
[y] => 1
)
)
Array TWO-
Array
(
[0] => Array
(
[label] => July 18 2020
[y] => 0
)
[1] => Array
(
[label] => July 19 2020
[y] => 0
)
[2] => Array
(
[label] => July 20 2020
[y] => 0
)
[3] => Array
(
[label] => July 21 2020
[y] => 0
)
)
To
desired output array
Array
(
[0] => Array
(
[label] => July 18 2020
[y] => 1
)
[1] => Array
(
[label] => July 19 2020
[y] => 0
)
[2] => Array
(
[label] => July 20 2020
[y] => 3
)
[3] => Array
(
[label] => July 21 2020
[y] => 0
)
)
I have tried
array_merge($arrayone, $arraytwo);
but it doesn't work.
Is it possible to get the desired output ?
This is how array looks like - https://imgur.com/a/HUQUmZz
Please share your thoughts on this.
Thankyou
With your arrays, I do not think there is a smart way to do it, but this should work :
<?php
$datesArray = [
[
'label' => 'July 18 2020',
'y' => 0,
],
[
'label' => 'July 19 2020',
'y' => 0,
],
[
'label' => 'July 20 2020',
'y' => 0,
],
[
'label' => 'July 21 2020',
'y' => 0,
],
];
$valuesArray = [
[
'label' => 'July 20 2020',
'y' => 3,
],
[
'label' => 'July 18 2020',
'y' => 1,
],
];
foreach($datesArray as &$dateArray) {
foreach($valuesArray as $valueArray) {
// use ?? if php version allows it, else do isset($valueArray['label']) ? $valueArray['label'] : null;
$currentLabel = $valueArray['label'] ?? null;
if ($currentLabel === $dateArray['label']) {
$dateArray['y'] = $valueArray['y'] ?? 0;
}
}
}
print_r($datesArray);
return $datesArray;
Result :
Array
(
[0] => Array
(
[label] => July 18 2020
[y] => 1
)
[1] => Array
(
[label] => July 19 2020
[y] => 0
)
[2] => Array
(
[label] => July 20 2020
[y] => 3
)
[3] => Array
(
[label] => July 21 2020
[y] => 0
)
)
This will take quadratic time, if you need something faster you will have to change the indices of your arrays to make a faster lookup.
snippet

sort a multidimensional array according to 3 keys (day,month,year) in php

I have a multidimensional array like this one ( each $orders[$userid] array has multiple arrays of orders)
foreach($orders[$userid] as $order){
print_r($order);
}
This is the first user's orders grouped by date,month,year
Array ( [id] => 409079 [user_id] => 26017 [total] => 30 [final_total] => 29.1 [order_status_id] => 1
[day] => 1 [month] => 11 [year] => 2016 [amount2] => 2198.2999696731567 )
Array ( [id] => 410744 [user_id] => 26017 [total] => 175 [final_total] => 165 [order_status_id] => 1
[day] => 2 [month] => 11 [year] => 2016 [amount2] => 2619.799982070923 )
Array ( [id] => 412268 [user_id] => 26017 [total] => 300 [final_total] => 293 [order_status_id] => 1
[day] => 3 [month] => 11 [year] => 2016 [amount2] => 4413.400000572205 )
Array ( [id] => 405860 [user_id] => 26017 [total] => 10 [final_total] => 9.8 [order_status_id] => 1
[day] => 30 [month] => 10 [year] => 2016 [amount2] => 352.5999994277954 )
Array ( [id] => 407500 [user_id] => 26017 [total] => 85 [final_total] => 84.5 [order_status_id] => 1
[day] => 31 [month] => 10 [year] => 2016 [amount2] => 1135.1000022888184 )
As you see older dated are displayed after recent dates. The question is how to sort this multidimensional array to display old dates then recent dates like this
Array ( [id] => 405860 [user_id] => 26017 [total] => 10 [final_total] => 9.8 [order_status_id] => 1
[day] => 30 [month] => 10 [year] => 2016 [amount2] => 352.5999994277954 )
Array ( [id] => 407500 [user_id] => 26017 [total] => 85 [final_total] => 84.5 [order_status_id] => 1
[day] => 31 [month] => 10 [year] => 2016 [amount2] => 1135.1000022888184 )
Array ( [id] => 409079 [user_id] => 26017 [total] => 30 [final_total] => 29.1 [order_status_id] => 1
[day] => 1 [month] => 11 [year] => 2016 [amount2] => 2198.2999696731567 )
Array ( [id] => 410744 [user_id] => 26017 [total] => 175 [final_total] => 165 [order_status_id] => 1
[day] => 2 [month] => 11 [year] => 2016 [amount2] => 2619.799982070923 )
Array ( [id] => 412268 [user_id] => 26017 [total] => 300 [final_total] => 293 [order_status_id] => 1
[day] => 3 [month] => 11 [year] => 2016 [amount2] => 4413.400000572205 )
Please use code:
foreach ($orders as $key => $row) {
$year[$key] = $row['year'];
$month[$key] = $row['month'];
$day[$key] = $row['day'];
}
array_multisort($year, SORT_ASC, $month, SORT_ASC, $day, SORT_ASC, $orders);
While in more complex situations you would use array_multisort, in this case, you can reduce the problem to sort only by one value. The
'year', 'month' and 'day' are basically parts of the date. Using usort function you can do the following:
$dateToTimestamp = function (array $order) {
$day = $order['day'];
$month = $order['month'];
$year = $order['year'];
return strtotime("$day-$month-$year");
};
usort($array, function ($a, $b) use ($dateToTimestamp) {
return $dateToTimestamp($a) - $dateToTimestamp($b);
});
One thing to pay attention with strtotime you cannot really set a locale in order to recognize which part of the string is a day, month, or year. In one of PHP manual comments, there is a trick to compensate this. In our case, the use of dash separator ensures the order.
Here is working demo.

unset all id keys from multidimensional array

How to unset all keys named id from a multidimensional array?
private function remove_id(Array &$arr){
foreach($arr as $key => $value){
if($key == 'id'){
unset($arr[$key]);
}
elseif(is_array($value)){
$this->remove_id($value);
}
}
}
array
Array
(
[id] => 52453
[periods] => Array
(
[0] => Array
(
[id] => 95296
[is_readonly] => 0
[year] => 2016
[month] => 1
)
[1] => Array
(
[id] => 95297
[is_readonly] => 0
[year] => 2016
[month] => 2
)
[2] => Array
(
[id] => 95298
[is_readonly] => 0
[year] => 2016
[month] => 3
)
[3] => Array
(
[id] => 95299
[is_readonly] => 0
[year] => 2016
[month] => 4
)
[4] => Array
(
[id] => 95300
[is_readonly] => 0
[year] => 2016
[month] => 5
)
[5] => Array
(
[id] => 95301
[is_readonly] => 0
[year] => 2016
[month] => 6
)
[6] => Array
(
[id] => 95302
[is_readonly] => 0
[year] => 2016
[month] => 7
)
[7] => Array
(
[id] => 95303
[is_readonly] => 0
[year] => 2016
[month] => 8
)
[8] => Array
(
[id] => 95304
[is_readonly] => 0
[year] => 2016
[month] => 9
)
[9] => Array
(
[id] => 95305
[is_readonly] => 0
[year] => 2016
[month] => 10
)
[10] => Array
(
[id] => 95306
[is_readonly] => 0
[year] => 2016
[month] => 11
)
[11] => Array
(
[id] => 95307
[is_readonly] => 0
[year] => 2016
[month] => 12
)
)
[closing_profit_amount] => 0
[closing_profit_net_amount] => 0
)
You need to use &value in the for loop to keep changes in nested arrays.
Also the array cannot have more than 1 id key, so there is no need to check it within the loop, which allow a bit of microoptimization here:
private function remove_id(Array &$arr){
if(isset($arr['id'])) {
unset($arr['id']);
}
foreach($arr as &$value){
if(is_array($value)){
$this->remove_id($value);
}
}
}

Include month if not there in php array

I have an array like this in php
Array
(
[0] => Array
(
[month] => April-2014
[total_booking] => 2
)
[1] => Array
(
[month] => May-2014
[total_booking] => 5
)
[2] => Array
(
[month] => June-2014
[total_booking] => 25
)
[3] => Array
(
[month] => October-2013
[total_booking] => 1
)
[4] => Array
(
[month] => July-2014
[total_booking] => 4
)
)
I have to make this array
if i selected two months from_month , to_month if there are no any months in this array it should be included eg:
i have selected from_month 2014 feb to_month 2014 may . but if in my array only 2014 feb, 2014 april,2014 may only so iwat to include 2014 march in correct place.
like this
Array
(
[month] => March-2014
[total_booking] => 0
)
this is my code
foreach ($newarray as $month => total_booking) {
//sorting
}
foreach ($newarray as $month => total_booking) {
//if there is no month in array betwean to_month and from_month it
should be included in correct place as sorted
}
The best way is to take reference from the start date and end date you inputted and look it up in the master array..
Here it is(please scroll for answer)
$your_array=array
(
array
(
'month' => 'April-2014',
'total_booking' => 2
),
array
(
'month' => 'May-2014',
'total_booking' => 5
),
array
(
'month' => 'June-2014',
'total_booking' => 25
),
array
(
'month' => 'October-2013',
'total_booking' => 1
),
array
(
'month' => 'July-2014',
'total_booking' => 4
)
);
$start_date="Jan 1 2013";
$end_date="Dec 31 2014";
$timestamp1=strtotime($start_date);
$timestamp2=strtotime($end_date);
for($i=$timestamp1;$i<$timestamp2;$i=$i+24*60*60){
//echo $i;
$gapmonth[]=date('F-Y',$i);
}
$gapmonth=array_unique($gapmonth);
//convert $dataS(ORIGINAL ARRAY) to one dimentional array so the life will be easier
foreach($your_array as $val){
$derived_val[$val['month']]=$val['total_booking'];
}
foreach($gapmonth as $val){
if(array_key_exists($val,$derived_val)){
$total_booking=$derived_val[$val];
}
else{
$total_booking=0;
}
$finaldate[]=array('month'=>$val,'total_booking'=>$total_booking);
}
echo "<pre>";
print_r($finaldate);
OUTPUTS
Array
(
[0] => Array
(
[month] => January-2013
[total_booking] => 0
)
[1] => Array
(
[month] => February-2013
[total_booking] => 0
)
[2] => Array
(
[month] => March-2013
[total_booking] => 0
)
[3] => Array
(
[month] => April-2013
[total_booking] => 0
)
[4] => Array
(
[month] => May-2013
[total_booking] => 0
)
[5] => Array
(
[month] => June-2013
[total_booking] => 0
)
[6] => Array
(
[month] => July-2013
[total_booking] => 0
)
[7] => Array
(
[month] => August-2013
[total_booking] => 0
)
[8] => Array
(
[month] => September-2013
[total_booking] => 0
)
[9] => Array
(
[month] => October-2013
[total_booking] => 1
)
[10] => Array
(
[month] => November-2013
[total_booking] => 0
)
[11] => Array
(
[month] => December-2013
[total_booking] => 0
)
[12] => Array
(
[month] => January-2014
[total_booking] => 0
)
[13] => Array
(
[month] => February-2014
[total_booking] => 0
)
[14] => Array
(
[month] => March-2014
[total_booking] => 0
)
[15] => Array
(
[month] => April-2014
[total_booking] => 2
)
[16] => Array
(
[month] => May-2014
[total_booking] => 5
)
[17] => Array
(
[month] => June-2014
[total_booking] => 25
)
[18] => Array
(
[month] => July-2014
[total_booking] => 4
)
[19] => Array
(
[month] => August-2014
[total_booking] => 0
)
[20] => Array
(
[month] => September-2014
[total_booking] => 0
)
[21] => Array
(
[month] => October-2014
[total_booking] => 0
)
[22] => Array
(
[month] => November-2014
[total_booking] => 0
)
[23] => Array
(
[month] => December-2014
[total_booking] => 0
)
)
Loop through it and test if values are missing:
$prev_month = false;
foreach($your_array as $k=>$values){
if($prev_month!==false){ // first itteration will be empty, dont do useless checks
// Test if themonth after the previous month matches this one
if( $prev_month+1 !== $values['month'] ){
// FILL IN THE BLANKS
// splice in at position $thisIndex (<- this you'll have to do)
array_splice( $prev_month, $thisIndex-1, 0, $newDateBookingsArray); // -1, we want it before this item!
// (dont forget to loop in case more than 1 items miss)
}
}
$prev_month = $values['month']; // save value for next round
}
Edit: TS first asked to sort the array, the code to use a custom sort can be found in the edits of this post.

MSSQL / PHP - assistance with query and resultset to get data for bar chart

I am trying to create a bar chart that shows monthly hits for the past 12 months.
I have the below query:
SELECT
(MONTH(date)) AS MONTH
, (YEAR(date)) AS YEAR
, SUM(hits) AS count
FROM [statistics]
WHERE ID = '". $id ."'
AND (date > DATEADD(yy, - 1, GETDATE()))
GROUP BY (MONTH(date)), (YEAR(date))
ORDER BY year, month
This provides the below resultset:
Array
(
[0] => Array
(
[Admin] => Array
(
[month] => 7
[year] => 2012
[count] => 702
)
)
[1] => Array
(
[Admin] => Array
(
[month] => 8
[year] => 2012
[count] => 650
)
)
[2] => Array
(
[Admin] => Array
(
[month] => 9
[year] => 2012
[count] => 670
)
)
[3] => Array
(
[Admin] => Array
(
[month] => 10
[year] => 2012
[count] => 66
)
)
[4] => Array
(
[Admin] => Array
(
[month] => 11
[year] => 2012
[count] => 53
)
)
[5] => Array
(
[Admin] => Array
(
[month] => 12
[year] => 2012
[count] => 39
)
)
[6] => Array
(
[Admin] => Array
(
[month] => 1
[year] => 2013
[count] => 54
)
)
[7] => Array
(
[Admin] => Array
(
[month] => 2
[year] => 2013
[count] => 36
)
)
[8] => Array
(
[Admin] => Array
(
[month] => 3
[year] => 2013
[count] => 48
)
)
)
This only shows the months that it has results for but I need all months whether they have results or not (so count would be 0). What I need is something more like the below which includes all 12 months:
Array
(
[0] => Array
(
[Admin] => Array
(
[month] => 7
[year] => 2012
[count] => 702
)
)
[1] => Array
(
[Admin] => Array
(
[month] => 8
[year] => 2012
[count] => 650
)
)
[2] => Array
(
[Admin] => Array
(
[month] => 9
[year] => 2012
[count] => 670
)
)
[3] => Array
(
[Admin] => Array
(
[month] => 10
[year] => 2012
[count] => 66
)
)
[4] => Array
(
[Admin] => Array
(
[month] => 11
[year] => 2012
[count] => 53
)
)
[5] => Array
(
[Admin] => Array
(
[month] => 12
[year] => 2012
[count] => 39
)
)
[6] => Array
(
[Admin] => Array
(
[month] => 1
[year] => 2013
[count] => 54
)
)
[7] => Array
(
[Admin] => Array
(
[month] => 2
[year] => 2013
[count] => 36
)
)
[8] => Array
(
[Admin] => Array
(
[month] => 3
[year] => 2013
[count] => 48
)
)
[9] => Array
(
[Admin] => Array
(
[month] => 4
[year] => 2013
[count] => 0
)
)
[10] => Array
(
[Admin] => Array
(
[month] => 5
[year] => 2013
[count] => 0
)
)
[11] => Array
(
[Admin] => Array
(
[month] => 6
[year] => 2013
[count] => 0
)
)
)
Can anyone suggest which would be the best way to achieve this? Could it be done in the SQL or does it need to be done in the code? If so, how?
Many thanks in advance.
This can be achieved through PHP using a loop which iterates all the possible months, and if there is data for that month, add it to an output array, otherwise, insert a blank entry with count of 0 for that month
EDIT
Example solution;
$m = $resultset[0]['Admin']['month'];
$y = $resultset[0]['Admin']['year'];
for ($i = 0; $i < 12; $i++) {
$adj = ((($i - 1) + $m) % 12) + 1;
if (!(isset($resultset[$i]['Admin']['month']) && $resultset[$i]['Admin']['month'] == $adj)) {
array_splice($resultset, $i, 0, array(array(
'Admin' => array(
'month' => $adj,
'year' => $y + ($i + $m > 12),
'count' => 0
)
)));
}
}
The important part for solving your issue is the line;
$adj = ((($i - 1) + $m) % 12) + 1;
This translates $i from being an integer between 0-11 to a month between 1-12, depending on the starting month ($m)
Well try this code it may help
foreach ($array as $year => $values) {
for ($i = 1; $i <= 12; $i++) { // Loop through months 1 .. 12
if (!$values[$i]) {
echo "0";
} else {
echo $values[$i];
}
}
}

Categories