1
votes

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!

2
I think moment.js won't help much here.D. Pardal
@0stone0 parsing the day and check if the next day value is +1 but it wasn't a success.devinthemaking
@D.Pardal do you have any suggestion?devinthemaking
Are you literally just asking how to take the first and last items/substrings of a string? What do you need moment.js for? Not seeing any dates, just a simple string?goto1

2 Answers

1
votes

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) + "'"))
0
votes

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