我正在寻找一个功能,如果连续3天或更多天相互跟随,则会从工作日序列中删除一周中的几天。这是我的测试代码(使用Test::More测试框架)
// function is($result, $expected, $message)
is(drop_days(""), "", 'Empty');
is(drop_days("Mo"), "Mo", 'One Day');
is(drop_days("Mo,Tu"), "Mo,Tu", 'Two Days');
is(drop_days("Mo,Tu,We"), "Mo-We", 'Three Days');
is(drop_days("Mo,Tu,We,Th,Fr,Sa,Su"), "Mo-Su", 'Seven Days');
is(drop_days("Mo,Tu,Th,Fr"), "Mo,Tu,Th,Fr", 'Four days with gap');
is(drop_days("Mo,Tu,We,Fr"), "Mo-We,Fr", '3 consecutive days, one single day');
is(drop_days("Mo,Tu,We,Fr,Sa,Su"), "Mo-We,Fr-Su", '2 pairs of 3 consecutive days');
答案 0 :(得分:4)
有时候“愚蠢”的方法是最聪明的
function drop_days($s) {
static $map = array(
'Mo,Tu,We,Th,Fr,Sa,Su' => 'Mo-Su',
'Mo,Tu,We,Th,Fr,Sa' => 'Mo-Sa',
'Mo,Tu,We,Th,Fr' => 'Mo-Fr',
'Mo,Tu,We,Th' => 'Mo-Th',
'Mo,Tu,We' => 'Mo-We',
'Tu,We,Th,Fr,Sa,Su' => 'Tu-Su',
'Tu,We,Th,Fr,Sa' => 'Tu-Sa',
'Tu,We,Th,Fr' => 'Tu-Fr',
'Tu,We,Th' => 'Tu-Th',
'We,Th,Fr,Sa,Su' => 'We-Su',
'We,Th,Fr,Sa' => 'We-Sa',
'We,Th,Fr' => 'We-Fr',
'Th,Fr,Sa,Su' => 'Th-Su',
'Th,Fr,Sa' => 'Th-Sa',
'Fr,Sa,Su' => 'Fr-Su',
);
return strtr($s, $map);
}
答案 1 :(得分:1)
另一种方法:
function drop_days( $str, $days = 'mo,tu,we,th,fr,sa,su' ) {
$days_i_s = array_flip( explode( ',', $days ) );
$days_i_n = explode( ',', $days );
$day_string = str_replace( array_keys( $days_i_s ), array_values( $days_i_s ), strtolower( $str ) );
return str_replace( array_values( $days_i_s ), array_keys( $days_i_s ), preg_replace_callback( '~(0,1,2,3,4,5,6)|(1,2,3,4,5,6)|(0,1,2,3,4,5)|(1,2,3,4,5)|(2,3,4,5,6)|(0,1,2,3,4)|(0,1,2,3)|(0,1,2)|(3,4,5,6)|(2,3,4,5)|(2,3,4)|(3,4,5)|(1,2,3,4)|(1,2,3)|(2,3,4)|(4,5,6)~', function($m) use($days_i_n){return $days_i_n[$m[0][0]].'-'.$days_i_n[$m[0][strlen($m[0])-1]] ;}, $day_string ) );
}
echo drop_days( "Mo,Tu,We,Fr,Sa,Su" );
答案 2 :(得分:0)
is()
位于http://codepad.org/ulJnW3Iu的示例。函数可以按任何顺序接受工作日。
<?php
function drop_days($string, $atleast = 3) {
$weekdays = 'Mo,Tu,We,Th,Fr,Sa,Su';
$weekdays = explode(',', $weekdays);
$selected = array();
$sequences = array();
foreach ($weekdays as $weekday)
$selected[] = (strpos($string,$weekday)!==false);
$i = 0;
while ($i<count($weekdays)) {
if (!$selected[$i]) {
$i++;
continue;
}
if ($i+$atleast<=count($weekdays)) {
for ($j=$i+1; $j<count($weekdays); $j++) {
if ($selected[$j]) {
if ($j+1<count($weekdays)) continue;
$sequences[] = $weekdays[$i] . '-' . $weekdays[$j];
break 2;
} else {
if ($j-$i>=$atleast)
$sequences[] = $weekdays[$i] . '-' . $weekdays[$j-1];
else
for ($k=$i; $k<$j; $k++) $sequences[] = $weekdays[$k];
$i = $j+1;
break;
}
}
} else {
$sequences[] = $weekdays[$i];
$i++;
}
}
return implode(',', $sequences);
}
?>