Define a lookup as a constant to easily determine the sequential position of each day.
Explode the string on commas and iterate the day values.
If the result string is empty, add the day with no delimiter/glue.
If the day is a consecutively positioned day, then potentially remove the appended yesterday substring if it was attached using a hyphen, then append a hyphen and the day.
If the day is not a consecutively positioned day, then append a comma and the day.
Code: (Demo)
define('DAYS', array_flip(['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']));
function condenseDays(string $days): string
{
$result = '';
foreach (explode(',', $days) as $day) {
if (!$result) {
$result .= $day;
} elseif (DAYS[$day] === DAYS[$yesterday] + 1) {
$result = str_replace("-$yesterday", '', $result) . "-$day";
} else {
$result .= ",$day";
}
$yesterday = $day;
}
return $result;
}
echo condenseDays('mon,tue,wed,thu,fri,sat') . "\n";
echo condenseDays('tue,thu,fri,sun') . "\n";
echo condenseDays('mon,tue,wed,fri,sat,sun') . "\n";
echo condenseDays('mon,thu,sun') . "\n";
echo condenseDays('tue,wed,fri,sat') . "\n";
echo condenseDays('mon,wed,fri,sun') . "\n";
echo condenseDays('mon,tue,thu,fri,sat,sun');
Output:
mon-sat
tue,thu-fri,sun
mon-wed,fri-sun
mon,thu,sun
tue-wed,fri-sat
mon,wed,fri,sun
mon-tue,thu-sun
Alternatively, if you'd rather use a brute-force approach, you can replace commas to hyphens for all neighboring days, then use regex to remove the "guts" of multi-consecutive days.
Code: (Demo)
define(
'PAIRS',
[
[
'mon,tue',
'tue,wed',
'wed,thu',
'thu,fri',
'fri,sat',
'sat,sun'
],
[
'mon-tue',
'tue-wed',
'wed-thu',
'thu-fri',
'fri-sat',
'sat-sun'
]
]
);
function condenseDays(string $days): string
{
return preg_replace(
'/-\K[^,]+-/',
'',
str_replace(PAIRS[0], PAIRS[1], $days)
);
}
Sneakiest / Least-intelligible version where range-worthy commas are identified by their neighboring letter instead of 3-letter days.
Code: (Demo)
function condenseDays(string $days): string
{
return preg_replace(
'/-\K[^,]+-/',
'',
str_replace(
['n,t', 'e,w', 'd,t', 'u,f', 'i,s', 't,s'],
['n-t', 'e-w', 'd-t', 'u-f', 'i-s', 't-s'],
$days
)
);
}