У меня действительно возникают проблемы с пониманием того, как написать логику для приведенного ниже требования на javascript / typescript. Мне нужно использовать только javascript или машинописный текст (без jquery и других фреймворков)

Вот данные в БД

Mon  : 9:00AM - 7:00PM
Tue  : 9:00AM - 10:00PM
Wed  : 9:00AM - 7:00PM
Thu  : 9:00AM - 7:00PM
Fri  : 9:00AM - 7:00PM
Sat  : 10:00AM - 4:00PM
Sun  : 11:00AM - 5:00PM

Мне нужно использовать приведенные выше данные и начать группировку в Javascript / Typescript

Результат после рендеринга в javascript / typescript должен выглядеть так:

Mon,Wed- Fri : 9:00AM - 7:00PM 
Tue : 9:00AM - 10:00PM 
Sat  : 10:00AM - 4:00PM 
Sun  : 11:00AM - 5:00PM
0
RKCY 15 Окт 2020 в 21:09

1 ответ

Лучший ответ

Я уверен, что кто-то может сделать его более элегантным, но я решил проблему именно так.

let rows = [
"Mon  : 9:00AM - 7:00PM",
"Tue  : 9:00AM - 10:00PM",
"Wed  : 9:00AM - 7:00PM",
"Thu  : 9:00AM - 7:00PM",
"Fri  : 9:00AM - 7:00PM",
"Sat  : 10:00AM - 4:00PM",
"Sun  : 11:00AM - 5:00PM"
]

  /**
   * We need to create an array, which will contain the days that will br grouped by AM and PM.
   * Expected output: 
   * [
   *   {
   *      days: [
   *         {Mon: 0},
   *         {Wed: 2},
   *         {Thu: 3},
   *         {Fri: 4}
   *      ],
   *      am: 9:00AM
   *      pm: 7:00PM
   *   },
   *   {
   *       days: [
   *          {Tue: 1}
   *       ],
   *       am: 9:00AM,
   *       pm: 10:00PM
   *   }, ...
   * ]
   */

let groups = [];

rows.forEach((row, index) => {
  let parts = row.split(" : ");
  let day = parts[0].trim();
  let am = parts[1].split("-")[0].trim();
  let pm = parts[1].split("-")[1].trim();
  // Let's see if an item with the same AM and PM has been pushed into array.
  let group = groups.find(x => x.am === am && x.pm === pm);
  if (group) {
    group.days.push({[day]: index});
  } else {
    let group = {
      days: [{[day]: index}],
      am: am,
      pm: pm
    }
    groups.push(group);
  }
})

/**
 * Now, we can loop through groups array, and if there is more than a day in any array item,
 * we will create a loop there. The tricky part is to create a string like Mon - Fri for consecutive days.
 * To do that, I decided to check the index of day, prevDay, and nextDay. If they are consecutive numbers
 * instead of adding the day to string add "-". If the string has already "-" at its end, just skip. 
 */

let finale = [];

groups.forEach(group => {
  if (group.days.length > 1) {
    let days = "";
    for (let i = 0; i < group.days.length; i++) {
      let day = group.days[i];
      let prevDay = group.days[i-1];
      let nextDay = group.days[i+1];
      let dayName = Object.keys(day)[0];
      let dayIndex = Object.values(day)[0];
      let prevDayIndex = prevDay ? Object.values(prevDay)[0] : null;
      let nextDayIndex = nextDay ? Object.values(nextDay)[0] : null;
      if (i === 0) {
        days = dayName;
      } else if (i === group.days.length - 1) {
        days = `${days}, ${dayName}`;
      } else {
        if (nextDayIndex - dayIndex === 1 && dayIndex - prevDayIndex === 1) {
          if (days.slice(-2) !== "- ") {
            days = `${days} - `;
          }
        } else {
          days = `${days}, ${dayName}`;
        }
      }
    }
    days = days.replace("- ,", "-")
    finale.push(`${days} : ${group.am} - ${group.pm}`)
  } else {
    finale.push(`${Object.keys(group.days[0])[0]} : ${group.am} - ${group.pm}`)
  }
})
console.log(finale)


finale = ["Mon, Wed - Fri : 9:00AM - 7:00PM", "Tue : 9:00AM - 10:00PM", "Sat : 10:00AM - 4:00PM", "Sun : 11:00AM - 5:00PM"]

2
Bülent Akgül 16 Окт 2020 в 06:37