如何根据PHP中依赖于其值的索引拆分数组


How do I split an array depending at an index that is dependant on its value in PHP?

基本上,当有人试图预订连续10天以上的假期时,我会尝试生成一个警告,并且我已经设法在每组之后(当连续的假期结束时)获得了一个以END为元素的数组,但我不知道如何将数组拆分,以便每次有10天或更多的连续假期被预订时,我都可以访问日期范围。这是当前代码:

/* == CURRENT INPUT === */ 
$bankhols[]="2016-05-30";
$bankhols[]="2016-08-29";
$bankhols[]="2016-12-26";
$bankhols[]="2016-12-27";
$bankhols[]="2017-01-02";
$bankhols[]="2017-04-14";
$bankhols[]="2017-04-17";
$bankhols[]="2017-05-01";
$bankhols[]="2017-05-29";
$bankhols[]="2017-08-28";
$bankhols[]="2017-12-25";
$bankhols[]="2017-12-26";
$ten_days_check = array(
    '2016-07-16',
    '2016-07-17',
    '2016-07-18',
    '2016-07-19',
    '2016-07-20',
    '2016-07-21',
    '2016-07-22',
    '2016-07-23',
    '2016-07-24',
    '2016-07-25',
    '2016-07-26',
    '2016-07-27',
    '2016-07-28',
    '2016-07-29',
    '2016-07-30',
    '2016-07-31',
    '2016-08-01',
    '2016-08-02',
    '2016-08-03',
    '2016-08-04',
    '2016-08-05',
    '2016-08-06',
    '2016-08-07',
    '2016-08-08',
    '2016-08-09',
    '2016-08-10',
    '2016-08-11',
    '2016-08-12',
    //'2016-08-13',
    '2016-08-14',
    '2016-08-15',
    '2016-08-16',
    '2016-08-17',
    '2016-08-18',
    '2016-08-19',
    '2016-08-20',
    '2016-08-21',
    '2016-08-22',
    '2016-08-23',
    '2016-08-24',
    '2016-08-25',
    '2016-08-26',
    '2016-08-27',
    '2016-08-28',
    '2016-08-29',
    '2016-08-30',
);
/* === ENDINPUT === */ 

$counter = 0;
foreach($ten_days_check as $date) {
    $datetime = strtotime($date);
    $nextday = date('Y-m-d', strtotime($date . ' + 1 day'));

    if(date('N', $datetime) != 6 && date('N', $datetime) != 7 && !in_array($date, $bankhols)) {
        $counter++;
        $set_of_ten[] = $date;
    }
    if(!in_array($nextday, $ten_days_check)) {
        if($date != $ten_days_check[count($ten_days_check) - 1]) {
            //$set_of_ten[] = $counter;
            $set_of_ten[] = "END";
            $counter = 0;
        } else {
            //$set_of_ten[] = $counter;
            $set_of_ten[] = "END";
        }
    }
}

我想指出一个事实,即2016-07-16和2016-07-26之间的日期超过了连续10天,并在所有超过10天的日期(当然不包括银行假日和周末)继续这样做。

我不太理解你的问题,但如果你试图将日期数组分组为每个10的数组,那么你可能正在寻找array_chunk

$days_group = array_chunk($ten_days_check , 10);

这将把数组分布成一个多维数组,每个数组有10个元素。

附带说明一下,如果我要在自己的代码中实现"当有人试图预订连续10天以上的假期时生成警告"的功能,我会执行以下操作。

  1. 捕获用户进行预订的日期并将其存储在一个数组中,例如$bookings
  2. 每次用户提交预订时,我都会在$bookings数组中添加日期
  3. $bookings上运行array_unique以筛选出重复的预订
  4. 计算阵列中的预订数量
  5. 如果计数大于10,则意味着我们需要应用警告逻辑
  6. 使用简单的php逻辑检查数组中是否有10个连续的日期。

    1. 以asc对数组进行排序
    2. 遍历数组并为找到的连续日期保留一个计数器
    3. 如果找到不连续的日期,则将其重置
    4. 如果计数>10警告
  7. 如果找到,生成警告。

  8. 利润
<?php
function has_ten_consecutive_days($dates) {
    sort($dates);
    $last = null;
    $consec = 0;
    foreach($dates as $date) {
        $ts = strtotime($date);
        if($last) {
            $between = $ts - $last;
            if($between == 24 * 60 * 60) {
                $consec++;
                if($consec == 10)
                    return true;
            } else {
                $consec = 0;
            }
        }
        $last = $ts;
    }
    return false;
}

创建一些日期来测试以上内容:

function timestamps_to_dateish($timestamps) {
    return array_map(
        function($item) {
            return date('Y-m-d', $item);
        },
        $timestamps
    );
}
// Create some sample data
$first_ts = strtotime('2016-07-27');
$timestamps = array(); 
// Build a list of 13 consecutive days in timestamps
foreach(range(0,12) as $num) {
    $timestamps[] = $first_ts + $num * 24 * 60 * 60;
}
$ts1 = $timestamps;
$ts2 = $timestamps;
$ts2[6] += 7 * 24 * 60 * 60; // Replace the 7th day with a day a week after
$dates1 = timestamps_to_dateish($ts1);
$dates2 = timestamps_to_dateish($ts2);
var_dump($dates1);
var_dump(has_ten_consecutive_days($dates1));
var_dump($dates2);
var_dump(has_ten_consecutive_days($dates2));

输出:

array (size=13)
  0 => string '2016-07-27' (length=10)
  1 => string '2016-07-28' (length=10)
  2 => string '2016-07-29' (length=10)
  3 => string '2016-07-30' (length=10)
  4 => string '2016-07-31' (length=10)
  5 => string '2016-08-01' (length=10)
  6 => string '2016-08-02' (length=10)
  7 => string '2016-08-03' (length=10)
  8 => string '2016-08-04' (length=10)
  9 => string '2016-08-05' (length=10)
  10 => string '2016-08-06' (length=10)
  11 => string '2016-08-07' (length=10)
  12 => string '2016-08-08' (length=10)
boolean true
array (size=13)
  0 => string '2016-07-27' (length=10)
  1 => string '2016-07-28' (length=10)
  2 => string '2016-07-29' (length=10)
  3 => string '2016-07-30' (length=10)
  4 => string '2016-07-31' (length=10)
  5 => string '2016-08-01' (length=10)
  6 => string '2016-08-09' (length=10)
  7 => string '2016-08-03' (length=10)
  8 => string '2016-08-04' (length=10)
  9 => string '2016-08-05' (length=10)
  10 => string '2016-08-06' (length=10)
  11 => string '2016-08-07' (length=10)
  12 => string '2016-08-08' (length=10)
boolean false