phparraysdatemappinggrouping

Map dates array with values array and group by day of the week filling missing dates with 0 values


I have an array of dates and values, for example:

$dates = ['2014-12-01', '2014-12-02', '2014-12-08', '2014-12-09', '2014-12-10', '2014-12-11'];
$values = [5, 3, 7, 8, 9, 2];

You'll note that 12/01 is a Monday, as is 12/08. I'd like to group data from these two arrays by day if the week:

[
    'monday' => [5, 7],
    'tuesday' => [3, 8],
    'wednesday' => [0, 9],
    'thursday' => [0, 2],
]

You'll note that the arrays are formed by grabbing the values associated with the days of the week. However, in the case that a Wednesday date exists, for example, but the prior Tuesday does not, then the array should have a "0". In other words, the 4 arrays should all be the same length.

NOTE: So far, I have only determined how to find the day of the week from a date: date('l', strtotime("2014-12-08")); I really can't figure out the general algorithm to solve this.


Solution

  • $dates  = array( '2014-12-01','2014-12-02','2014-12-08','2014-12-09',
                     '2014-12-10','2014-12-11' );
    $values = array( 5, 3, 7, 8, 9, 2 );
    
    $date  = strtotime(min($dates));
    $stop  = strtotime(max($dates));
    $dates = array_flip($dates);
    $out   = array();
    
    while($date <= $stop)
    {
       $tmp = date('Y-m-d', $date);
       $out[date('l', $date)][] = isset($dates[$tmp]) && isset($values[$dates[$tmp]]) ?
                                  $values[$dates[$tmp]] : 0;  
       $date = strtotime('+1 day', $date);   
    }
    
    print_r($out);
    

    Result:

    Array
    (
        [Monday] => Array
            (
                [0] => 5
                [1] => 7
            )
    
        [Tuesday] => Array
            (
                [0] => 3
                [1] => 8
            )
    
        [Wednesday] => Array
            (
                [0] => 0
                [1] => 9
            )
    
        [Thursday] => Array
            (
                [0] => 0
                [1] => 2
            )
    
        [Friday] => Array
            (
                [0] => 0
            )
    
        [Saturday] => Array
            (
                [0] => 0
            )
    
        [Sunday] => Array
            (
                [0] => 0
            )
    
    )
    

    ps: how can I get the an array of all the dates included in the "dates" array associated with only all the Mondays?

    Modify the code as, for example:

       $tmp = date('Y-m-d', $date);
       $exists = isset($dates[$tmp]) && isset($values[$dates[$tmp]]);
       $out[date('l', $date)]['numbers'][] = $exists ? $values[$dates[$tmp]] : 0; 
       if ($exists) $out[date('l', $date)]['dates'][] = $tmp;
       $date = strtotime('+1 day', $date);  
    

    You'll get an output as (example for monday)

    [Monday] => Array
        (
            [numbers] => Array
                (
                    [0] => 5
                    [1] => 7
                )
    
            [dates] => Array
                (
                    [0] => 2014-12-01
                    [1] => 2014-12-08
                )
    
        )