2016-10-01 2 views
1

У меня есть массив, у которого есть дата начала и окончания в ключе/значении. например.Алгоритм для комбинирования диапазонов дат в PHP

/* formate 'mm/dd/yyyy'=> 'mm/dd/yyyy'*/ 

$arr = array(
'01/01/2016'=>'01/01/2016', 
'01/02/2016'=>'01/02/2016', 
'01/03/2016'=>'01/03/2016', 


'04/10/2016'=>'04/10/2016', 
'04/11/2016'=>'04/11/2016', 
'04/12/2016'=>'04/12/2016', 


'04/25/2016'=>'04/25/2016', 

'04/30/2016'=>'04/30/2016', 
'05/01/2016'=>'05/01/2016', 
'05/02/2016'=>'05/02/2016' } 

) 

Здесь вы можете увидеть, что какой-то элемент имеет непрерывные даты. например. первые три элемента имеют даты от 04/01 до 04/03. Я хочу это в одном элементе. поэтому новый массив должен быть таким>

$arr = array(
    '01/01/2016'=>'01/03/2016', 

    '04/10/2016'=>'04/12/2016', 

    '04/25/2016'=>'04/25/2016', 

    '04/30/2016'=>'05/02/2016' 
}) 

Как это сделать?

Благодаря

+0

Даты будет в порядке возрастания или нет? –

+0

Да, должен быть месяц/дата/год мудрым. Основной массив BTW уже в правильном порядке. –

ответ

2

Я знаю, что есть уже ответ, но вот моя версия - потратили немного времени на него так хотелось доля!

Как и в вашем примере, я предполагаю, что ваш исходный массив находится в порядке даты, а ключи и значения всегда одинаковы.

Вы можете использовать функцию для перебора исходного набора данных и возвращает массив сгруппированных дат следующим образом ...

function group_dates($dates_array) { 

    // prepare results array 
    $result = array(); 

    // take the first date from the submitted array 
    $group_start = array_shift($dates_array); 
    $timestamp_previous_iteration = strtotime($group_start); 

    // iterate over remaining values 
    foreach ($dates_array as $date) { 
     // calculate current iteration's timestamp 
     $timestamp_current = strtotime($date); 

     // calculate timestamp for 1 day before the current value 
     $timestamp_yesterday = strtotime('-1 day', $timestamp_current); 

     if ($timestamp_previous_iteration != $timestamp_yesterday) { 
     // create group... 
     $result[$group_start] = date('m/d/Y', $timestamp_previous_iteration); 
     // ...and store the next group's start date 
     $group_start = $date; 
     } 

     // log timestamp for next iteration 
     $timestamp_previous_iteration = $timestamp_current; 
    } 

    // add final group 
    $result[$group_start] = date('m/d/Y', $timestamp_previous_iteration); 

    return $result; 
} 

Вы можете использовать функцию следующим образом,

$result_array = group_dates($arr); 

При подаче функции массив в вашем примере приведет к массиву по вашему запросу.

Поскольку ваши даты отформатированы MM/DD/YYYY, строка будет правильно преобразована в временную метку unix на strtotime(). Если вы использовали другие форматы дат, вам нужно взглянуть на объект PHP DateTime.

Эталонные
http://php.net/manual/en/function.strtotime.php
http://php.net/manual/en/book.datetime.php

+0

Хорошо. Спасибо –

1

Проверить код ниже

<?php 

    $arr = array(
     '01/01/2016'=>'01/01/2016', 
     '01/02/2016'=>'01/02/2016', 
     '01/03/2016'=>'01/03/2016', 
     '04/10/2016'=>'04/10/2016', 
     '04/11/2016'=>'04/11/2016', 
     '04/12/2016'=>'04/12/2016', 
     '04/25/2016'=>'04/25/2016', 
     '04/30/2016'=>'04/30/2016', 
     '05/01/2016'=>'05/01/2016', 
     '05/02/2016'=>'05/02/2016' 
    ); 

    $lastDate = null; 
    $ranges = array(); 
    $currentRange = array(); 

    foreach ($arr as $date => $value) { 
     $temp = $value; 
     $value = date_create(date('m/d/Y', strtotime($value))); 

     if (null === $lastDate) { 
      $currentRange[] = $temp; 
     } else { 
      // get the Date object 
      $interval = date_diff($value, $lastDate); 

      if ($interval->days === 1) { 
       // add this date to the current range 
       $currentRange[] = $temp;  
      } else { 
       // store the old range and start a new 
       $ranges[] = $currentRange; 
       $currentRange = array($temp); 
      } 
     } 
     $lastDate = $value; 
    } 

    $ranges[] = $currentRange; 

    $datemerge = array(); 
    foreach ($ranges as $key) { 
     $count = count($key); 
     $datemerge[$key[0]] = $key[$count-1]; 
    } 

    print_r($datemerge); 

?> 

Выход:

Array 
(
    [01/01/2016] => 01/03/2016 
    [04/10/2016] => 04/12/2016 
    [04/25/2016] => 04/25/2016 
    [04/30/2016] => 05/02/2016 
) 
+0

Хорошо. Спасибо –

Смежные вопросы