Search Array for Best Match based on Day & Time

陌路散爱 提交于 2020-01-25 06:56:08

问题


I'm trying to work out how to the the correct Site base on the current Day and Time from an array. The examples array just shows Monday, the real array will contain 7 days of the week with multiple values for each day.

This is the example array :

$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')
);

So Monday at 1100 I should get NW1, at 1800 I should get RE1, but between 1200-1300 I should get PL1

So far this is the code I have:

$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";

This works for times between 0830-1730 & 1730-2130, but not if the time is 1200-1300.

I'm assuming I need to search the array for the Day match, then the Start time and check the end time, but I'm not sure how to do this ?

Can anyone point me in the right direction.

Thanks

**** UPDATE **** New example array with additional entries

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
        )
}

The expected results are:

0940 = PK1
1430 = PL1
0920 = NW1

The aim is 0830 to 1730 NW1 is correct unless something else overrides this, ie 1200-2100 PL1 would be correct, after 2100 to 2130 RE1 etc.

Thanks


回答1:


All you need to do is reverse the sorting based on start time

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']);
});

This way, we will loop through the array starting with the latest start time (for each day) and once we find a match, we break the loop, using the site value for the match.

I'm still not really sure of the purpose of the multiplication in your usort, but it doesn't seem to be causing any problems, so I'm going to leave it in.

DEMO




回答2:


As far as I can see as soon as you find a $time between the "start" and "end" you assign the value to $site and then "break" straight away without looking through the rest of the array.

But if the time is 1230 on a Monday which entry in the array should take precedence?

If it is the last one, then maybe hang on to a variable until you search the entire array like so:

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

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


来源:https://stackoverflow.com/questions/58998146/search-array-for-best-match-based-on-day-time

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!