Как определить, находится ли каждая дата в массиве между датами в других массивах - PullRequest
0 голосов
/ 03 мая 2019

У меня есть массив с датами. Я должен определить, какие даты принадлежат каким периодам. Для этой цели у меня есть два других массива - один с датами начала и один с датами окончания этих периодов.

Я пробовал циклы foreach для дат и класса DatePeriod, но не смог заставить его работать.

foreach ($dates as $value) {
  foreach ($startdates as $key => $value1) {
    foreach ($enddates as $key => $value2) {
      if ($value > $value1 && $value < $value2) {
        result[$value] = $key;
      }
    }
  }
}

даты (выдержка) / $ даты

$dates = Array ( [0] => 2011-04-11 
                [1] => 2011-06-28 
                [2] => 2011-09-26 
                [3] => 2012-01-02 
                [4] => 2012-05-12 )

даты начала с назначенными ключами (извлечение) / $ startdates

Array ( [10] => 2011-01-01 
        [20] => 2011-07-01 
        [30] => 2012-01-01 
        [40] => 2012-07-01 )

даты окончания с назначенными ключами (извлечение) / $ enddates

Array ( [10] => 2011-06-30 
        [20] => 2011-12-31 
        [30] => 2012-06-30 
        [40] => 2012-12-31 )

Я бы хотел, чтобы результатом стал новый массив, в котором даты в массиве $ date становятся ключами, а периоды в массивах дат начала и конца становятся такими:

Array ( [2011-04-11] => 10 
        [2011-06-28] => 10 
        [2011-09-26] => 20 
        [2012-01-02] => 30 
        [2012-05-12] => 30 )

Ответы [ 2 ]

1 голос
/ 03 мая 2019

Поскольку вы сравниваете даты в формате Ymd, вам не нужны функции даты / времени - другими словами, просто обрабатывайте даты как строки.

Одновременно выполняйте итерацию начального и конечного элементов.Когда вы найдете правильный диапазон, сохраните данные и перейдите к следующей дате для оценки.

Код: ( Демо )

$dates = ['2011-04-11', '2011-06-28', '2011-09-26', '2012-01-02', '2012-05-12'];
$startdates = [
    10 => '2011-01-01',
    20 => '2011-07-01',
    30 => '2012-01-01',
    40 => '2012-07-01'
];
$enddates = [
    10 => '2011-06-30',
    20 => '2011-12-31',
    30 => '2012-06-30',
    40 => '2012-12-31'
];

foreach ($dates as $date) {
    foreach ($startdates as $key => $startdate) {
        if ($date >= $startdate && $date <= $enddates[$key]) {
            $result[$date] = $key;
            continue 2;
        }
    }
    $result[$date] = 'out of bounds';
}
var_export($result);

Вывод:

array (
  '2011-04-11' => 10,
  '2011-06-28' => 10,
  '2011-09-26' => 20,
  '2012-01-02' => 30,
  '2012-05-12' => 30,
)
1 голос
/ 03 мая 2019

Вы можете зацикливать свою основную переменную дат для периода начальных и конечных массивов дат,

// combining keys and values
$temp   = array_combine($startdates, $enddates);
$result = [];
// & for making changes on assigned address of variable regardless of array_walk function scope
array_walk($dates, function ($item, $key) use (&$result, $temp, $startdates) { 
    foreach ($temp as $k => $v) {
        // comparing with start and end date range
        if (strtotime($item) >= strtotime($k) && strtotime($item) <= strtotime($v)) {
            // searching by value and getting key
            $result[$item] = array_search($k, $startdates); 
            // if comes to this loop break as its never gonna come here
            break;
        }
    }
});

array_combine - Создает массив, используя один массив для ключей и другой для его значений
array_walk - применить предоставленную пользователем функцию к каждому члену массива
array_search - Выполняет поиск в массиве заданного значения и возвращает первый соответствующий ключ в случае успеха

выход

Array
(
    [2011-04-11] => 10
    [2011-06-28] => 10
    [2011-09-26] => 20
    [2012-01-02] => 30
    [2012-05-12] => 30
)

Демо .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...