2

I currently have 2 arrays;

$last_12_months - contains an array of the last 12 months from the current month

$app12_array_temp - contains a query result with a count of appointments made in that month, and a month.

I need to be able to loop through each month, and assign an appointment count to that month.

As i am nesting the loop, i am getting this as a result:

[0,0,0,0,0,0,0,"1",0,0,0,0,0,0,"4",0,0,0,0,0,0,"2",0,0,0,0,0,0,"15",0,0,0,0,0,0,"9",0,0,0,0,0,0,"8",0,0,0,0,0,0,"2",0,0,0,0,0,0,"1",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]

What I need is:

[0,0,0,0,1,4,2,15,9,8,2,1]

my current script is:

//Loop through months, and check if appointments happened in that month 
  foreach($last_12_months as $m => $month){
    foreach($app_12_array_temp AS $app){
      if(date("m", strtotime($app['time'])) == date("m", strtotime($month))){
        $app_12_array[] = $app['count'];
        break;
      }else{
        $app_12_array[] = 0;
      }
    }
  }

So if there is an appointment in that month, it should add the appointment count to an array, else add 0. Currently, it is adding 0 every time the loop isnt that corresponding month

I have tried using Breaks when condition met but will return 0 up until it finds that data.

I have also tried In_Array(), but just returns [0,0,0,0,1,0,0,0,0,0,0,0]

This is what the script should be thinking, but I can't think of how to get it to do this:

Jan -> Any data for this month? -> No, so add 0 for this month to array
Feb -> Any data for this month? -> No, so add 0 for this month to array
Mar -> Any data for this month? -> Yes, so add $app['count'] to array
Apr -> Any data for this month? -> Yes, so add $app['count'] to array
May -> Any data for this month? -> Yes, so add $app['count'] to array

EDIT

$app_12_array_temp = [
    ['time' => '2019-07-27 13:00:00', 'count' => '1'],
    ['time' => '2019-08-26 13:00:00', 'count' => '2'],
    ['time' => '2019-09-06 13:00:00', 'count' => '8'],
    ['time' => '2019-10-22 12:00:00', 'count' => '9'],
    ['time' => '2019-11-21 12:00:00', 'count' => '15'],
    ['time' => '2019-12-27 11:00:00', 'count' => '2'],
    ['time' => '2020-01-22 15:00:00', 'count' => '4'],
    ['time' => '2020-02-12 09:00:00', 'count' => '1'],
];

$last_12_months = ['Feb', 'Jan', 'Dec', 'Nov', 'Oct', 'Sep', 'Aug', 'Jul', 'Jun', 'May', 'Apr', 'Mar'];
7
  • Hello, can you add the content of the $last_12_months and $app_12_arr_temp arrays to the question, please ? Commented Feb 13, 2020 at 11:54
  • Done :) Added it as an edit Commented Feb 13, 2020 at 11:58
  • “contains a query result with a count of appointments made in that month, and a month” - not really, it contains a specific date, instead of an actual month. Do you have ensured there will be only one per month, or could it be more? Commented Feb 13, 2020 at 12:02
  • The result groups by month so will only ever be 1 record for each month, with a count of how many in that month. As you can tell, in the loop, I extracted the month from the timestamp. No result is given back if no appointments for the grouped month. so hence I need to loop through each month and check if there is a matching month in the appointment array. Commented Feb 13, 2020 at 12:05
  • 2
    … or get rid of the second array with the month names altogether. You have all the info you need in your first array already, all you’d need to do is format those dates as just the month name, instead of sticking one arbitrary date somewhere in the month in there. Commented Feb 13, 2020 at 12:09

2 Answers 2

1

try this, using the month as the key for the new array

$app_12_array_temp = [
    ['time' => '2019-07-27 13:00:00', 'count' => '1'],
    ['time' => '2019-08-26 13:00:00', 'count' => '2'],
    ['time' => '2019-09-06 13:00:00', 'count' => '8'],
    ['time' => '2019-10-22 12:00:00', 'count' => '9'],
    ['time' => '2019-11-21 12:00:00', 'count' => '15'],
    ['time' => '2019-12-27 11:00:00', 'count' => '2'],
    ['time' => '2020-01-22 15:00:00', 'count' => '4'],
    ['time' => '2020-02-12 09:00:00', 'count' => '1'],
];

$last_12_months = ['Feb', 'Jan', 'Dec', 'Nov', 'Oct', 'Sep', 'Aug', 'Jul', 'Jun', 'May', 'Apr', 'Mar'];


$app_12_array = array_fill_keys( $last_12_months, 0 );
foreach ( $last_12_months as $m => $month )
{
    foreach ( $app_12_array_temp AS $app )
    {
        if ( date( "m", strtotime( $app['time'] ) ) == date( "m", strtotime( $month ) ) )
        {
            $app_12_array[ $month ] = ($app_12_array[ $month ] ?? 0 ) + $app['count'];
            break;
        }
    }
}

var_dump( $app_12_array );
Sign up to request clarification or add additional context in comments.

3 Comments

This is returning something closer to what i am looking for, but not in same order as the last 12 months array, and months that dont have data should show as 0 in the array for that corresponding month. The result of your suggestion: {"Feb":1,"Jan":4,"Dec":2,"Nov":15,"Oct":9,"Sep":8,"Aug":2,"Jul":1}
(see edit) you can initialize the "template" array with 0
Had issues with your solution only to find that it didnt like converting $month to a date()... so just left it as $month rather than DATE('m', strtotime($month))
0

This is one way you can solve your problem, using a do-while loop. This can easily be used for a shorter/longer range of period then 12 months by modifying the $dateFirst variable.

Code:

$data = [
    ['time' => '2019-07-27 13:00:00', 'count' => '1'],
    ['time' => '2019-08-26 13:00:00', 'count' => '2'],
    ['time' => '2019-09-06 13:00:00', 'count' => '8'],
    ['time' => '2019-10-22 12:00:00', 'count' => '9'],
    ['time' => '2019-11-21 12:00:00', 'count' => '15'],
    ['time' => '2019-12-27 11:00:00', 'count' => '2'],
    ['time' => '2020-01-22 15:00:00', 'count' => '4'],
    ['time' => '2020-02-12 09:00:00', 'count' => '1'],
];

usort($data, function($a, $b) {
    return strtotime($a['time']) - strtotime($b['time']);
});

if (!is_array($data) || count($data) === 0) {
    die('no data');
}

$dateFirst = (date('Y', time()) - 1) . date('-m', time());

// begin 11 months ago instead of 12 [start]
if (date('n', strtotime($dateFirst)) == 12) {
    $dateFirst = (date('Y', strtotime($dateFirst)) + 1) . '-01';
} else {
    $newMonth = (date('n', strtotime($dateFirst)) + 1);
    $dateFirst = date('Y', strtotime($dateFirst)) . '-' . ($newMonth <= 9 ? '0' . $newMonth : $newMonth);
}
// begin 11 months ago instead of 12 [end]

$dateCurrent = $dateFirst;
$tsDateNow = strtotime(date('Y-m', time()));

$result = [];

do {
    if (!isset($result[$dateCurrent])) {
        $result[$dateCurrent] = 0;
    }

    for ($i = 0; $i < count($data); $i++) {
        $dateCheck = date('Y-m', strtotime($data[$i]['time']));

        if ($dateCheck === $dateCurrent) {
            $result[$dateCurrent] += $data[$i]['count'];
        }
    }

    if (date('n', strtotime($dateCurrent)) == 12) {
        $dateCurrent = (date('Y', strtotime($dateCurrent)) + 1) . '-01';
    } else {
        $newMonth = (date('n', strtotime($dateCurrent)) + 1);
        $dateCurrent = date('Y', strtotime($dateCurrent)) . '-' . ($newMonth <= 9 ? '0' . $newMonth : $newMonth);
    }

} while (strtotime($dateCurrent) <= $tsDateNow);
// exclude this month:
// } while (strtotime($dateCurrent) < $tsDateNow);

print_r($result);

Outputs:

Array
(
    [2019-03] => 0
    [2019-04] => 0
    [2019-05] => 0
    [2019-06] => 0
    [2019-07] => 1
    [2019-08] => 2
    [2019-09] => 8
    [2019-10] => 9
    [2019-11] => 15
    [2019-12] => 2
    [2020-01] => 4
    [2020-02] => 1
)

This code will also sum all count if you have multiple elements with different dates within the same month.

So if you have the following array:

$data = [
    ['time' => '2019-07-27 13:00:00', 'count' => '1'],
    ['time' => '2019-08-26 13:00:00', 'count' => '2'],
    ['time' => '2019-09-06 13:00:00', 'count' => '8'],
    ['time' => '2019-10-22 12:00:00', 'count' => '9'],
    ['time' => '2019-07-04 09:00:00', 'count' => '1000'],
    ['time' => '2019-11-21 12:00:00', 'count' => '15'],
    ['time' => '2019-12-27 11:00:00', 'count' => '2'],
    ['time' => '2020-01-22 15:00:00', 'count' => '4'],
    ['time' => '2020-02-12 09:00:00', 'count' => '1'],
];

This will be the output:

Array
(
    [2019-03] => 0
    [2019-04] => 0
    [2019-05] => 0
    [2019-06] => 0
    [2019-07] => 1001
    [2019-08] => 2
    [2019-09] => 8
    [2019-10] => 9
    [2019-11] => 15
    [2019-12] => 2
    [2020-01] => 4
    [2020-02] => 1
)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.