Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How I can count the number of days of each nested arrays group

I’m trying to extend my code and add the total of days of the nested arrays

$free_time_frame = [[]];  // nested array here

$start = new DateTime("2022-01-01");
$end = new DateTime("2022-12-31");

$interval = new DateInterval("P1M"); // 1 month interval
$period = new DatePeriod($start, $interval, $end);
$seasons = [2];

foreach ($period as $key => $date) {
    if (in_array($date->format("n"), $seasons)) {
        // Skip the rest of the loop if the current month is in the $seasons array
        if (!empty($free_time_frame[array_key_last($free_time_frame)])) {

            $free_time_frame[] = [];   // append nested array
        }
        continue;
    }

    // Set the start date to the first day of the month
    $start_date = new DateTime($date->format("Y-m-01"));
    // Set the end date to the last day of the month
    $end_date = new DateTime($date->format("Y-m-t"));

    // Calculate the number of days between the start and end dates
    $diff = $start_date->diff($end_date);
    $days = $diff->days + 1; // Add 1 to include the end date
    // use the latest nested array
    $free_time_frame[array_key_last($free_time_frame)][] = [
        "season" => (int) $date->format("n"),
        "elapse" => $days,
        "from" => $start_date->format("Y-m-d"),
        "to" => $end_date->format("Y-m-d"),
    ];

    $start->modify("+1 month");
}
return $free_time_frame;

Expected output :

[
    'totalDays' => 31 // if there is only one month otherwise count all the months days of that array
    'frame' =>
    [ 
     [
            "season" => 1,  // January
            "elapse" => 31,   // that's why I have 31 in totalDays
            "from" => $start_date->format("Y-m-d"),
            "to" => $end_date->format("Y-m-d"),
    ]
   ]
]

As you can see I have totalDays => 31 because I have only one Frame, so the total is 31

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Thank you for your help

>Solution :

You could modify your created arrays afterwards with the array_reduce function.

foreach($free_time_frame as &$current_time_frame) // use a reference here for inplace modification
  $current_time_frame = ['totalDays' => array_reduce($current_time_frame, fn($aggr, $v) => $aggr + $v['elapse'])] + $current_time_frame;

The array_reduce function takes a callback function which here sums up the field elapse.

<?php declare(strict_types = 1);

$free_time_frame = [[]];  // nested array here

$start = new DateTime("2022-01-01");
$end = new DateTime("2022-12-31");

$interval = new DateInterval("P1M"); // 1 month interval
$period = new DatePeriod($start, $interval, $end);
$seasons = [2];

foreach ($period as $key => $date) {
  if (in_array($date->format("n"), $seasons)) {
    // Skip the rest of the loop if the current month is in the $seasons array
    if (!empty($free_time_frame[array_key_last($free_time_frame)])) {

      $free_time_frame[] = [];   // append nested array
    }
    continue;
  }

  // Set the start date to the first day of the month
  $start_date = new DateTime($date->format("Y-m-01"));
  // Set the end date to the last day of the month
  $end_date = new DateTime($date->format("Y-m-t"));

  // Calculate the number of days between the start and end dates
  $diff = $start_date->diff($end_date);
  $days = $diff->days + 1; // Add 1 to include the end date
  // use the latest nested array
  $free_time_frame[array_key_last($free_time_frame)][] = [
    "season" => (int) $date->format("n"),
    "elapse" => $days,
    "from" => $start_date->format("Y-m-d"),
    "to" => $end_date->format("Y-m-d"),
  ];

  $start->modify("+1 month");
}


foreach($free_time_frame as &$current_time_frame)
  $current_time_frame = ['totalDays' => array_reduce($current_time_frame, fn($aggr, $v)=>$aggr + $v['elapse'])] + $current_time_frame;

echo json_encode($free_time_frame, JSON_PRETTY_PRINT);

Result:

[
    {
      "totalDays": 31,
        "0": {
      "season": 1,
            "elapse": 31,
            "from": "2022-01-01",
            "to": "2022-01-31"
        }
    },
    {
      "totalDays": 306,
        "0": {
      "season": 3,
            "elapse": 31,
            "from": "2022-03-01",
            "to": "2022-03-31"
        },
        "1": {
      "season": 4,
            "elapse": 30,
            "from": "2022-04-01",
            "to": "2022-04-30"
        },
        "2": {
      "season": 5,
            "elapse": 31,
            "from": "2022-05-01",
            "to": "2022-05-31"
        },
        "3": {
      "season": 6,
            "elapse": 30,
            "from": "2022-06-01",
            "to": "2022-06-30"
        },
        "4": {
      "season": 7,
            "elapse": 31,
            "from": "2022-07-01",
            "to": "2022-07-31"
        },
        "5": {
      "season": 8,
            "elapse": 31,
            "from": "2022-08-01",
            "to": "2022-08-31"
        },
        "6": {
      "season": 9,
            "elapse": 30,
            "from": "2022-09-01",
            "to": "2022-09-30"
        },
        "7": {
      "season": 10,
            "elapse": 31,
            "from": "2022-10-01",
            "to": "2022-10-31"
        },
        "8": {
      "season": 11,
            "elapse": 30,
            "from": "2022-11-01",
            "to": "2022-11-30"
        },
        "9": {
      "season": 12,
            "elapse": 31,
            "from": "2022-12-01",
            "to": "2022-12-31"
        }
    }
]
Process finished with exit code 0
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading