首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从数组中删除重叠时间间隔

从数组中删除重叠时间间隔
EN

Stack Overflow用户
提问于 2019-08-02 05:00:18
回答 3查看 608关注 0票数 0

我有一个有时间间隔的数组

代码语言:javascript
运行
复制
$timeslots = array('9:00-10:00','10:00-11:00','11:00-12:00','12:00-13:00','13:00-14:00','14:00-15:00','15:00-16:00','16:00-17:00','17:00-18:00','18:00-19:00','19:00-20:00','20:00-21:00');

现在我有两个时间间隔(动态)。

代码语言:javascript
运行
复制
$start="10:15";
$end="11:15";

现在我想从数组中删除两个时间间隔( 10:00到11:00和11:00到12:00 ),但是我的当前代码不能正常工作,我哪里错了?这是我的密码

代码语言:javascript
运行
复制
$key=array_search("10:15-11:15", $timeslots);
        unset($timeslots[$key]);
        $timeslotss=array_values($timeslots);
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-08-02 07:35:23

代码语言:javascript
运行
复制
<?php 
$timeslots = array('9:00-10:00','10:00-11:00','11:00-12:00','12:00-13:00','13:00-14:00','14:00-15:00','15:00-16:00','16:00-17:00','17:00-18:00','18:00-19:00','19:00-20:00','20:00-21:00');

$start="10:15";
$end="11:15";
$starttime = strtotime($start);
$endtime = strtotime($end);
foreach($timeslots as $time){   
    $key = array_search($time, $timeslots);

    $t = explode('-',$time);
    if(($starttime >= strtotime($t[0]) && $starttime <= strtotime($t[1])) ||($endtime > strtotime($t[0]) && $endtime < strtotime($t[1]))){
        unset($timeslots[$key]);
    }

}
echo'<pre>';print_r($timeslots);
?>
票数 0
EN

Stack Overflow用户

发布于 2019-08-02 05:47:58

代码语言:javascript
运行
复制
$timeslots = array('9:00-10:00','10:00-11:00','11:00-12:00','12:00-13:00','13:00-14:00','14:00-15:00','15:00-16:00','16:00-17:00','17:00-18:00','18:00-19:00','19:00-20:00','20:00-21:00');
$start="10:15";
$end="11:15";

$result = findTime($timeslots, $start, $end);
print_r($result);

function findTime($timeslots, $start, $end)
{
    $startArr = explode(':', $start);
    $endArr = explode(':', $end);
    foreach($timeslots as &$time) {
        if (strpos($time, $startArr[0]) === 0) {
          $timeArr = explode('-', $time);
          $time = $timeArr[0] . '-' . implode(':', $startArr);
        }
        if (strpos($time, $endArr[0]) === 0) {
          $timeArr = explode('-', $time);
          $time = implode(':', $endArr) . '-' . $timeArr[1];
        }
    }
    return $timeslots;
}

此代码适用于所询问的条件,但当start=10:15、end=10:30时,它将无法工作。虽然我有代码,但你自己做一些合乎逻辑的事情。

票数 0
EN

Stack Overflow用户

发布于 2019-08-02 07:17:46

解释

在这些情况下,可能会出现重叠时隙:

代码语言:javascript
运行
复制
(1)   S-----E
         S------E

(2)   S-----E
   S-----E

(3)   S-----E
        S-E

(4)   S-----E
    S----------E

S代表开始,E代表结束。现在我们可以得出结论,对于重叠的时间框架,动态时隙的开始或结束需要介于比较槽(1-3) 的开始和结束之间,或者开始和结束都必须在之前/之后,即比较槽(4)的开始和结束之间。

您的代码不工作,因为您只是比较字符串,并且您查找的字符串不包含在数组中。PHP不知道您的字符串是时间间隔。

解决方案

下面的代码应该可以解决您的问题。主要的逻辑是在TimeSlot::overlaps中,我们在这里比较两个插槽。然后将该方法与array_filter相结合,去除重叠时隙。

代码语言:javascript
运行
复制
class TimeSlot
{

    private $start;

    private $end;


    public function __construct(string $start, string $end)
    {
        $this->start = new DateTime($start);
        $this->end = new DateTime($end);
    }


    public function overlaps(TimeSlot $that): bool
    {
        return $this->start >= $that->start && $this->start <= $that->end
            || $this->end >= $that->start && $this->end <= $that->end
            || $this->start < $that->start && $this->end > $that->end;
    }


    public function __toString(): string
    {
        return $this->start->format('H:i')
            . '-'
            . $this->end->format('H:i');
    }
}


// Use the data from your example and other test cases
$dynamicSlot = new TimeSlot('10:15', '11:15');
// $dynamicSlot = new TimeSlot('11:00', '13:00');
// $dynamicSlot = new TimeSlot('15:15', '16:00');
// $dynamicSlot = new TimeSlot('10:15', '12:15');
$timeslots = [
    new TimeSlot('9:00', '10:00'),
    new TimeSlot('10:00', '11:00'),
    new TimeSlot('11:00', '12:00'),
    new TimeSlot('12:00', '13:00'),
    new TimeSlot('13:00', '14:00'),
    new TimeSlot('14:00', '15:00'),
    new TimeSlot('15:00', '16:00'),
    new TimeSlot('16:00', '17:00'),
    new TimeSlot('17:00', '18:00'),
    new TimeSlot('18:00', '19:00'),
    new TimeSlot('19:00', '20:00'),
    new TimeSlot('20:00', '21:00'),
];

// Remove overlapping slots
$filteredTimeSlots = array_filter(
    $timeslots,
    function (TimeSlot $current) use ($dynamicSlot) {
        return !$dynamicSlot->overlaps($current);
    }
);

// Echo result
foreach ($filteredTimeSlots as $slot) {
    echo $slot . '</br>';
}

对于动态插槽10:15-11:15,它将产生以下输出:

代码语言:javascript
运行
复制
12:00-13:00
13:00-14:00
14:00-15:00
15:00-16:00
16:00-17:00
17:00-18:00
18:00-19:00
19:00-20:00
20:00-21:00

当然不用上课也行,但我认为这样会更干净。请不要认为这是一个快速写入,因此缺乏适当的输入验证(当然,类应该在自己的源文件中驻留在自己的名称空间中)。

程序版本

正如您所问的,这里有另一个没有任何类的版本:

代码语言:javascript
运行
复制
<?php
$timeslots = [
    '9:00-10:00',
    '10:00-11:00',
    '11:00-12:00',
    '12:00-13:00',
    '13:00-14:00',
    '14:00-15:00',
    '15:00-16:00',
    '16:00-17:00',
    '17:00-18:00',
    '18:00-19:00',
    '19:00-20:00',
    '20:00-21:00',
];

$dynamicStart = mktime(10, 15);
$dynamicEnd = mktime(11, 15);

// $dynamicStart = mktime(11, 00);
// $dynamicEnd = mktime(13, 00);

// $dynamicStart = mktime(15, 15);
// $dynamicEnd = mktime(16, 00);

//$dynamicStart = mktime(10, 15);
//$dynamicEnd = mktime(12, 15);

foreach ($timeslots as $index => $slot) {
    list($curStart, $curEnd) = explode('-', $slot);
    $curStart = explode(':', $curStart);
    $curEnd = explode(':', $curEnd);
    $curStart = mktime($curStart[0], $curStart[1]);
    $curEnd = mktime($curEnd[0], $curEnd[1]);

    if ($dynamicStart >= $curStart && $dynamicStart <= $curEnd
        || $dynamicEnd >= $curStart && $dynamicEnd <= $curEnd
        || $dynamicStart < $curStart && $dynamicEnd > $curEnd) {
        unset($timeslots[$index]);
    }
}

print_r($timeslots);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57320187

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档