phparraysdatefilteringdate-comparison

Filter array by its date keys so that only the latest day of a year-month is retained


I have an array with Y-m-d-formatted keys. I want to filter the array so that the only rows kept will be associated with the latest day of a year-month.

Sample array:

array:4 [▼
  "2022-10-30" => array:9 [▶]
  "2022-10-31" => array:6 [▶]
  "2022-11-07" => array:4 [▶]
  "2022-11-09" => array:3 [▶]
]

Desired result:

array:2 [▼
  "2022-10-31" => array:6 [▶]
  "2022-11-09" => array:3 [▶]
]

Important : There may be other months in this array, and not every day of every month is representes in the input array.

I started to write some code, but I'm unsure how to proceed.

public function monthly_average()
{
    
    global $datas,$dates;
    $args= $this->period_monthAverage($datas,$dates);
    dump($args);
    //dump($datas);
    dump($dates);
    dump($dates[0]>$dates[1]);
    $fdate=array();

    for ($i = 0; $i <= sizeof($dates); $i++){
        if(date('m',strtotime($date[i]))==date('m',strtotime($date[i+1]))){

        }
        
       //dump((date('m',strtotime($date)))); 10- 11

    }

}

Solution

  • Maintain a lookup array of year-month keyed values where the values are the latest occurring day of the month on the calendar.

    When a later date in the month comes along, replace the elements in the result and update your lookup array.

    Code: (Demo)

    $result = [];
    foreach ($array as $key => $value) {
        $ym = substr($key, 0, 7);
        if (!isset($lookup[$ym]) || $lookup[$ym] < $key) {
            $result[$key] = $value;
            if (isset($lookup[$ym])) {
                unset($result[$lookup[$ym]]);
            }
            $lookup[$ym] = $key;
        }
    }
    var_export($result);
    

    Or written with fewer function calls: (Demo)

    $result = [];
    foreach ($array as $key => $value) {
        $ym = substr($key, 0, 7);
        if (!isset($lookup[$ym])) {
            $result[$key] = $value;
            $lookup[$ym] = $key;
        } elseif ($lookup[$ym] < $key) {
            unset($result[$lookup[$ym]]);
            $result[$key] = $value;
            $lookup[$ym] = $key;
        }
    }