phparraysmultidimensional-arraytext-formattinghyphenation

Format 2d array data into a string of hyphenated consecutive day ranges based on a shared time range


I am given data from an API in a format that is pretty difficult to use (in the manner that is necessary to be used in) - I do not have the ability to modify the API. Below is an example of the data I am given:

$data = array(
    array('day' => 'Monday', 'start' => 1100, 'end' => 1300),
    array('day' => 'Tuesday', 'start' => 1100, 'end' => 1300),
    array('day' => 'Wednesday', 'start' => 1100, 'end' => 1300),
    array('day' => 'Thursday', 'start' => 1200, 'end' => 1300),
    array('day' => 'Friday', 'start' => 1200, 'end' => 1300),
    array('day' => 'Saturday', 'start' => 1200, 'end' => 1300),
    array('day' => 'Sunday', 'start' => 1200, 'end' => 1400)
);

The data may not include all seven days of the week, start and end vary between 0000 and 2400. I am trying to come up with a way to format the data with the following output:

Monday - Wednesday (1100-1300), Thursday - Saturday (1200-1300), Sunday (1200-1400)

Basically, contiguous days (whose start and end times are the same) are separated by a hyphen.

I am kind of trying to avoid a huge block of ugly code.


Solution

  • Ugliness is in the eye of the beholder. ;) I think this is OK, but of course it might be exactly what you're trying to avoid.

    <?php
    $data = array(
        array('day' => 'Monday', 'start' => 1100, 'end' => 1300),
        array('day' => 'Tuesday', 'start' => 1100, 'end' => 1300),
        array('day' => 'Wednesday', 'start' => 1100, 'end' => 1300),
        array('day' => 'Thursday', 'start' => 1200, 'end' => 1300),
        array('day' => 'Friday', 'start' => 1200, 'end' => 1300),
        array('day' => 'Saturday', 'start' => 1200, 'end' => 1300),
        array('day' => 'Sunday', 'start' => 1200, 'end' => 1400)
    );
    
    $periods = array();
    
    $start = $end = $i = -1;
    
    foreach ($data as $datum) {
        if ($start != $datum['start'] || $end != $datum['end']) {
            $i++;
            $start = $datum['start'];
            $end   = $datum['end'];
    
            $periods[$i] = array(
                              'start'    => $start, 
                              'end'      => $end,
                              'startDay' => $datum['day']);
        }
        $periods[$i]['endDay'] = $datum['day'];
    }
    
    foreach ($periods as $k => $period) {
        echo ($k) ? ', ' : '';
        if ($period['startDay'] === $period['endDay']) {
            echo $period['startDay'];
        } else {
            echo "{$period['startDay']} - {$period['endDay']}";
        }
        echo " ({$period['start']} - {$period['end']})";
    }
    

    Would output:

    Monday - Wednesday (1100 - 1300), Thursday - Saturday (1200 - 1300), Sunday (1200 - 1400)