Reputation: 77
I have a string containing days of the week:
Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
It can be also:
Monday, Tuesday
Also:
Thursday, Friday, Saturday
What I want to achieve is if more than 2 days are consecutive to "merge" them and display like: Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday - will be Monday - Sunday; Monday, Tuesday - will stay like that; Thursday, Friday, Saturday - Thursday - Saturday.
I want to use only moment.js or javascript without other plugins (like range). Thanks in advance!
Upvotes: 1
Views: 812
Reputation: 30675
We can create a Day of the Week (dow) array with our list of days (and implicitly their indexes).
If a list of days are consecutive, we'll replace with Startday - Endday, though we won't bother if it's only two days.
I'm assuming that the week "wraps", e.g. Monday is considered to be consecutive to Sunday. If not, it's an easy tweak to make. We'd replace the function isModularConsecutive with isConsecutive.
function isModularConsecutive(a, modulus) {
return !isNaN(a.reduce((prev, current, index) => (index === 0 || current === ((prev + 1) % modulus) ? current: NaN)));
}
function formatDowList(input) {
const dow = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"];
let inputArray = input.split(/\s*\,\s*/);
let actualIndexes = inputArray.map(el => dow.findIndex(d => d === el));
if (!isModularConsecutive(actualIndexes, 7) || actualIndexes.length <= 2) {
return input;
}
return inputArray[0] + " - " + inputArray[inputArray.length-1];
}
/* Test the code */
const testInputs = ["Monday, Thursday, Friday", "Monday, Tuesday, Wednesday, Thursday, Friday", "Monday, Tuesday, Wednesday", "Sunday, Monday, Tuesday, Wednesday", "Monday, Wednesday", ];
testInputs.forEach(input => console.log("Input: '" + input + "'.", "Result: '" + formatDowList(input) + "'"))
Upvotes: 1
Reputation: 6587
This seems to work just fine.
const weekDaysMap = new Map([
["Monday", 0],
["Tuesday", 1],
["Wednesday", 2],
["Thursday", 3],
["Friday", 4],
["Saturday", 5],
["Sunday", 6]
]);
function getDayRanges(days) {
const ranges = [];
let range = [days[0]], d = weekDaysMap.get(days[0]);
for (let i = 1; i < days.length; i++) {
if (d !== (d = weekDaysMap.get(days[i])) - 1) {
range.push(days[i-1]);
ranges.push(range);
range = [days[i]];
}
}
range.push(days[days.length-1]);
ranges.push(range);
return ranges;
}
console.log(getDayRanges(["Monday", "Tuesday", "Wednesday", "Saturday", "Sunday"]).map( r => r.join("–")).join(", "))
Explanation: First we create a Map
that converts the days of the week to their indexes. Then we create a ranges
array that will store the start-end days pairs. We also define the current range
and the current day index, d
. We loop through the provided days of the week in the array and if the previous day in the array isn't the previous day in the order, the previous day in the array is the end of the range and the current day in the array is the start of a new one.
Then the each range is joined using an em dash and the ranges are joined using commas. (From [[Monday, Wednesday], [Saturday, Sunday]]
to Monday–Wednesday, Saturday–Sunday
.)
Upvotes: 0