简体   繁体   中英

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

Thank you for your help

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM