问题
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