【问题标题】:Search Array for Best Match based on Day & Time根据日期和时间搜索最佳匹配数组
【发布时间】:2019-11-22 16:24:54
【问题描述】:

我正在尝试根据数组中的当前日期和时间找出正确的站点。示例数组仅显示星期一,实际数组将包含一周中的 7 天,每天都有多个值。

这是示例数组:

$arr = array (
    array(  'Day' => 'Monday',
            'Start' => '0830',
            'End' => '1730',
            'Site' => 'NW1'),

    array(  'Day' => 'Monday',
            'Start' => '1200',
            'End' => '1300',
            'Site' => 'PL1'),

    array(  'Day' => 'Monday',
            'Start' =>'1730',
            'End' => '2130',
            'Site' => 'RE1')
);

所以星期一在1100 我应该得到NW1,在1800 我应该得到RE1,但是在1200-1300 我应该得到PL1

到目前为止,这是我拥有的代码:

$today = 'Monday'; // Full day name
$time = '1205';

echo "<br/>Day: $today";
echo "<br/>Time: $time <br/><br/>";


$arr = array (
    array(  'Day' => 'Monday',
            'Start' => '0830',
            'End' => '1730',
            'Site' => 'NW1'),

    array(  'Day' => 'Monday',
            'Start' => '1200',
            'End' => '1300',
            'Site' => 'PL1'),

    array(  'Day' => 'Monday',
            'Start' =>'1730',
            'End' => '2130',
            'Site' => 'RE1')
);

usort($arr, function($a, $b) {
    return (date("N", strtotime($a['Day'])) <=> date("N", strtotime($b['Day']))) * 100 +
           ($a['Start'] <=> $b['Start']) * 10 +
           ($a['End'] <=> $b['End']);
});

foreach ($arr as $i => $values) {
    if ($today != $values['Day']) continue;

    if ($time >= $values['Start'] && $time <= $values['End']) {
        $site = $values['Site'];
        break;
    }
}

echo "$today @ $time Site => $site";

这适用于0830-17301730-2130 之间的时间,但如果时间是1200-1300,则不适用。

我假设我需要在数组中搜索 Day 匹配,然后是 Start time 并检查 end time,但我不知道该怎么做?

谁能指出我正确的方向。

谢谢

**** 更新 **** 带有附加条目的新示例数组

Array
(
    [0] => Array
        (
            [Day] => Monday
            [Start] => 0830
            [End] => 1730
            [Site] => NW1
        )

    [1] => Array
        (
            [Day] => Monday
            [Start] => 0930
            [End] => 0945
            [Site] => PK1
        )

    [2] => Array
        (
            [Day] => Monday
            [Start] => 1200
            [End] => 2100
            [Site] => PL1
        )

    [3] => Array
        (
            [Day] => Monday
            [Start] => 1230
            [End] => 1245
            [Site] => EM1
        )

    [4] => Array
        (
            [Day] => Monday
            [Start] => 1730
            [End] => 2130
            [Site] => RE1
        )
}

预期结果是:

0940 = PK1
1430 = PL1
0920 = NW1

目标是 0830 到 1730 NW1 是正确的,除非有其他东西覆盖它,即 1200-2100 PL1 是正确的,在 2100 到 2130 RE1 等之后。

谢谢

【问题讨论】:

  • NW1 不能有两个条目有什么原因吗?
  • 你能解释一下你的usort逻辑吗?我不明白你为什么要做乘法。
  • @PatrickQ - 我不想将时间分成多个条目。每天可能有 4 或 5 个条目。 usort 是重新排序数组,我可能做错了!
  • 我希望你能真正解释你在 usort 中使用的逻辑,以便我更好地理解它。你可能做对了,也可能做错了。但除非你解释你在做什么(或至少试图做什么),否则我很难说它是什么。
  • "在 1200-1300 之间我应该得到 PL1"

标签: php arrays date time


【解决方案1】:

您需要做的就是根据开始时间反转排序

usort($arr, function($a, $b) {
    return (date("N", strtotime($a['Day'])) <=> date("N", strtotime($b['Day']))) * 100 +
           ($b['Start'] <=> $a['Start']) * 10 +
           ($a['End'] <=> $b['End']);
});

这样,我们将从最近的开始时间(每天)开始循环遍历数组,一旦找到匹配项,我们将使用匹配的站点值打破循环。

我仍然不确定您的 usort 中的乘法的目的,但它似乎没有造成任何问题,所以我将保留它。

DEMO

【讨论】:

    【解决方案2】:

    据我所知,一旦您在“开始”和“结束”之间找到 $time,您将值分配给 $site,然后立即“中断”而不查看数组的其余部分。

    但是如果时间是星期一的 1230,数组中的哪个条目应该优先?

    如果它是最后一个,那么可能会保留一个变量,直到您像这样搜索整个数组:

    $lastCorrectEntry;
    foreach ($arr as $i => $values) {
        if ($today != $values['Day']) continue;
    
        if ($time >= $values['Start'] && $time <= $values['End']) {
            $lastCorrectEntry = $values['Site'];
       }
    }
    $site = $lastCorrectEntry;
    

    【讨论】:

    • 嗨。在这个例子中,如果时间在 1200-1300 之间,那么它应该是 PL1
    猜你喜欢
    • 2021-02-11
    • 1970-01-01
    • 1970-01-01
    • 2021-09-17
    • 1970-01-01
    • 1970-01-01
    • 2021-03-20
    • 2013-08-01
    • 1970-01-01
    相关资源
    最近更新 更多