HiveBrain v1.2.0
Get Started
← Back to all entries
patternphpMinor

Get ranges from array of days

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
arrayrangesgetfromdays

Problem

I have an array of dates as input in the form "YYYY-mm-dd"=>category_id.0 (category_id counting from 0).

$days =array (
  '2014-10-15' => 49,
  '2014-10-16' => 49,
  '2014-10-17' => 49,
  '2014-10-18' => 0,
  '2014-10-19' => 0,
  '2014-10-20' => 0,
  '2014-10-21' => 0,
  '2014-10-22' => 0,
  '2014-10-23' => 0,
  '2014-10-24' => 0,
  '2014-10-25' => 0,
  '2014-10-26' => 0,
  '2014-10-27' => 0,
  '2014-10-28' => 0,
  '2014-10-29' => 0,
  '2014-10-30' => 0,
  '2014-10-31' => 0,
  '2014-11-01' => 0,
  '2014-11-02' => 0,
  /* MISSING 2014-11-03 */
  '2014-11-04' => 0,
  '2014-11-05' => 0,
  '2014-11-06' => 0,
  '2014-11-07' => 0,
  '2014-11-08' => 0,
  '2014-11-09' => 0,
  '2014-11-10' => 0,
  '2014-11-11' => 0,
  '2014-11-12' => 0,
  '2014-11-13' => 0,
  '2014-11-14' => 0,
  '2014-11-15' => 0,
  '2014-11-16' => 0,
  '2014-11-17' => 0,
  '2014-11-18' => 0,
  '2014-11-19' => 0,
  '2014-11-20' => 0,
  '2014-11-21' => 0,
  '2014-11-22' => 0,
  '2014-11-23' => 0,
  '2014-11-24' => 0,
  '2014-11-25' => 0,
  '2014-11-26' => 0,
  '2014-11-27' => 0,
  '2014-11-28' => 0,
  '2014-11-29' => 0,
  '2014-11-30' => 0,
  '2014-12-01' => 0,
  '2014-12-02' => 0,
  '2014-12-03' => 0,
  '2014-12-04' => 0,
  '2014-12-05' => 0,
  '2014-12-06' => 0,
  '2014-12-07' => 0,
  '2014-12-08' => 0,
  '2014-12-09' => 0,
  '2014-12-10' => 0,
  '2014-12-11' => 0,
  '2014-12-12' => 0,
  '2014-12-13' => 0,
  '2014-12-14' => 0,
  '2014-12-15' => 0,
  '2014-12-16' => 0,
  '2014-12-17' => 0,
  '2014-12-18' => 0,
  '2014-12-19' => 0,
  '2014-12-20' => 0,
  '2014-12-21' => 0,
  '2014-12-22' => 1,
  '2014-12-23' => 3,
  '2014-12-24' => 3,
  '2014-12-25' => 3,
  '2014-12-26' => 3,
  '2014-12-27' => 3,
  '2014-12-28' => 3,
  '2014-12-29' => 50,
  '2014-12-30' => 50,
  '2014-12-31' => 50,
  '2015-12-24' => 2,
  '2015-12-25' => 2,
);


I want to build an array of range of dates grouped by category_id.

For example, category_id 49 has 3 consecutive days from 15 to 17, so the first range should be:
`array('

Solution

This is the way I would do it:

function getRangeFromDays($days) {
  // collect dates into catagories
  foreach ($days as $date => $catagory) {
    $temp[$catagory][] = $date;
  }
  // process all dates in each catagory
  foreach ($temp as $catagory => $dates) {
    sort($dates);
    $startDate  = $dates[0];
    $finishDate = array_pop($dates);
    // walk through the dates, breaking at gaps
    foreach ($dates as $key => $date)
    if (($key > 0) && (strtotime($date)-strtotime($dates[$key-1]) > 99999)) {
      $result[] = array($startDate,$dates[$key-1],$catagory);
      $startDate = $date;
    }
    // force the end
    $result[] = array($startDate,$finishDate,$catagory);
  }
  return $result;
}

echo '';
print_r(getRangeFromDays($days));
echo '';


I use an intermediate array which makes it easier to get the results because it's already segmented by catagory. All that's then left to do is the date ranges. I turn dates into seconds to see if the gap is bigger than one day (> 99999 seconds).

Code Snippets

function getRangeFromDays($days) {
  // collect dates into catagories
  foreach ($days as $date => $catagory) {
    $temp[$catagory][] = $date;
  }
  // process all dates in each catagory
  foreach ($temp as $catagory => $dates) {
    sort($dates);
    $startDate  = $dates[0];
    $finishDate = array_pop($dates);
    // walk through the dates, breaking at gaps
    foreach ($dates as $key => $date)
    if (($key > 0) && (strtotime($date)-strtotime($dates[$key-1]) > 99999)) {
      $result[] = array($startDate,$dates[$key-1],$catagory);
      $startDate = $date;
    }
    // force the end
    $result[] = array($startDate,$finishDate,$catagory);
  }
  return $result;
}

echo '<pre>';
print_r(getRangeFromDays($days));
echo '</pre>';

Context

StackExchange Code Review Q#82989, answer score: 7

Revisions (0)

No revisions yet.