Javascript Array сортировать и составлять такое же расписание, как диапазон дней - PullRequest
0 голосов
/ 20 сентября 2018

Мне предоставляется CSV офисных расписаний с диапазоном тире для дней с таким же графиком.

Например, сегодня: Thursday:

Пн 3:00:00 - 21:00, вторник - четверг 5:30 - 21:30, пятница 7:15 - 10:00, суббота 8:00 - 15:00, вс закрыто

Мне нужно удалитьВ воскресенье закрытое расписание и сначала показывают Thursday, например, если сегодня Thursday

Мой ожидаемый результат примерно такой:

Вт - Четверг 5:30 утра - 9: 30:00, пятница с 7:15 до 22:00, суббота с 8:00 до 15:00, понедельник с 3:00 до 21:00 * 10101

Некоторые примеры и ожидаемые результаты, если сегодня Thursday (текущий день):

'Mon 4:00am - 9:00pm, Tue 6:00am - 9:30pm, Wed - Fri 5:30am - 9:30pm, Sat 8:00am - 3:00pm, Sun Closed' Ожидаемый результат: 'Tue 6:00am - 9:30pm, Wed - Fri 5:30am - 9:30pm, Sat 8:00am - 3:00pm, Mon 4:00am - 9:00pm'

'Wed 5:30am - 9:30pm, Thu 6:30am - 4:00pm, Fri - Tue 8:00am - 3:00pm, Sun Closed' Ожидаемый результат: 'Thu 6:30am - 4:00pm, Fri - Tue 8:00am - 3:00pm, 'Wed 5:30am - 9:30pm'

'Mon - Tue 5:30am - 9:30pm, Wed 6:30am - 4:00pm, Thu - Sat 8:00am - 3:00pm, Sun Closed' Ожидаемый результат: 'Thu - Sat 8:00am - 3:00pm, Mon - Tue 5:30am - 9:30pm, Wed 6:30am - 4:00pm'

Мой текущий код частично работает:

function sortDays(days) {
    var dayOfWeek = new Date().getDay();
    var list = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
    var sortedList = list.slice(dayOfWeek).concat(list.slice(0, dayOfWeek));
    return days.sort(function(a,b) { return sortedList.indexOf(a) > sortedList.indexOf(b); });
}

function removeA(arr) {
    var what, a = arguments, L = a.length, ax;
    while (L > 1 && arr.length) {
        what = a[--L];
        while ((ax= arr.indexOf(what)) !== -1) {
            arr.splice(ax, 1);
        }
    }
    return arr;
}

function getDaysRange(first, last) {
    // var week = new Array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday');
    var week = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];

    // Find first day
    var firstIndex = week.indexOf(first);
    // Shift array so that first day is index 0
    week = week.concat(week.splice(0, firstIndex));
    // Find last day
    var lastIndex = week.indexOf(last);

    // Cut from first day to last day and convert to CSV string
    // return week.slice(0, lastIndex + 1).toString();
    return week.slice(0, lastIndex + 1);
}



function reorderSchedule(schedule) {

    var detailedSchedule = [];
    var daysInWeek = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
    var scheduleExploded = schedule.split(',');
    var schedulehtms = '';

    console.log('===============================>>>>>>>>>>>>>>>>>>>');
    for (var i = 0, len = scheduleExploded.length; i < len; i++) {
        schedulehItem = scheduleExploded[i].trim();
        console.log(schedulehItem + ' = LOOP NUMBER ' + i + ' >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>');

        var count = (schedulehItem.match(/-/g) || []).length;
        console.log(count + " piece(s) of - found inside " + schedulehItem);

        if (count >= 2) {
            console.log(schedulehItem + ' is a range! ===============');

            // break down the days range
            var search = schedulehItem.search(/\d/);

            var scheduleOfRange = schedulehItem.substring(search, schedulehItem.length);
            console.log(scheduleOfRange);
            var daysRange = schedulehItem.substring(0, search - 1);
            console.log(daysRange);

            var arr = daysRange.split('-');
            var first = arr[0].trim();
            var second = arr[1].trim();

            var daysRange = getDaysRange(first, second);
            daysRange = removeA(daysRange, 'Sun');
            console.log(daysRange);
            console.log('>>>>>>>');

            for (x = 0; x < daysRange.length; x++) { 
                detailedSchedule.push(daysRange[x] + ' ' + scheduleOfRange);
            }

        } else {
            // insert the schedule in the final array
            detailedSchedule.push(schedulehItem);
        }

    }
    console.log('===============================>>>>>>>>>>>>>>>>>>>');
    console.log('=============');
    console.log(detailedSchedule);
    console.log('=============');

    var origDaysOnlyOrder = [];
    var daysWithScheduleOrder = [];
    var sortedDays = sortDays(daysInWeek);

    for (i = 0; i < detailedSchedule.length; i++) {        

        var myNewStr = detailedSchedule[i].substr(0, 3);
        // origDaysOnlyOrder.push(myNewStr);
        daysWithScheduleOrder[myNewStr] = detailedSchedule[i];
    }

    console.log('vvvvvvvvvvvvvvvvvvvvvvvvvvvv');
    console.log(daysWithScheduleOrder);
    console.log(sortedDays);

    var finalArray = [];
    for (i = 0; i < sortedDays.length; i++) {
        // don't insert undefined values
        if (typeof(daysWithScheduleOrder[sortedDays[i]]) != 'undefined') {
            // finalArray.push(daysWithScheduleOrder[sortedDays[i]]);
            finalArray[sortedDays[i]] = daysWithScheduleOrder[sortedDays[i]].substr(3).trim();
        }
    }

    // remove
    console.log(finalArray);
    console.log('######################>>>');

    // now in correct order then bring back the dash in the original range, check for same schedules then create the range
    // find first

    var scheduleObj = {};
    for (var key in finalArray) {
        var value = finalArray[key];
        // console.log(key, value);
        scheduleObj[key] = value;
    }
    console.log(scheduleObj);


    var hash = Object.create(null);
    var result = Object.create(null);

    Object.keys(scheduleObj).forEach(k => {
        var grp = scheduleObj[k];

        (grp in hash) ? hash[grp].push(k) : (hash[grp] = [k]);
    });

    for (key in hash) {
        if (hash[key].length > 1) {
            result[key] = hash[key].toString();
        }
    }

    console.log(hash);
    console.log('hash sa taas');


    var finalScheduleArray = [];
    // loop hash
    Object.keys(hash).forEach(function(key) {
        // console.log(key, result[key]);
        console.log(key, hash[key]);
        var my_key = key;
        var my_value = hash[key];


        if (my_value.length == 1) {
            finalScheduleArray[my_value] = my_key;
        } else {

            var rangeArray = [];
            for (i = 0; i < my_value.length; i++) {
                console.log(my_value[i]);
                rangeArray.push(my_value[i]);

            }
            console.log(rangeArray);

            var firstItem = rangeArray[0];
            var lastItem = rangeArray[rangeArray.length-1];
            finalScheduleArray[firstItem + ' - ' + lastItem] = my_key;
        }

    });

    console.log(finalScheduleArray);
    console.log('finalScheduleArray ----------');
    return 'zzz';
}

$(function() {
    // var schedule = 'Mon 4:00am - 9:00pm, Tue 6:00am - 9:30pm, Wed - Fri 5:30am - 9:30pm, Sat 8:00am - 3:00pm, Sun Closed'; // MALI Wed - Fri
    // var schedule = 'Mon 4:30am - 9:30pm, Tue 5:30am - 9:30pm, Wed 5:00am - 9:30pm, Thu - Sat 8:00am - 3:00pm, Sun Closed'; // tama Thu - Sat
    var schedule = 'Mon 3:00am - 9:00pm, Tue - Thu 5:30am - 9:30pm, Fri 7:15am - 10:00pm, Sat 8:00am - 3:00pm, Sun Closed'; // MALI Tue - Thu
    console.log(reorderSchedule(schedule));
});

Ответы [ 2 ]

0 голосов
/ 20 сентября 2018

Это свежий подход к размышлению о том, как бы я решил эту проблему:

const days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']

const parseDay = (daySched) => {
  const parts = daySched.match(/^(\w{3})( - (\w{3}))? (.+)$/)
  return {
    start: parts[1],
    end: parts[3] || parts[1],
    times: parts[4]
  }
}
const rotate = (idx) => (arr) => arr.slice(idx).concat(arr.slice(0, idx))

const makeSched = (schedStr) => {
  const schedule = schedStr.split(/\,\s+/).map(parseDay)
  return rotate(schedule.length - 1)(schedule) // put Sun first
}

const rotateSched = (schedule, day) => {
  const start = schedule.findIndex(d => days.indexOf(d.end) >= day)
  return rotate(start)(schedule) // perhaps not strictly necessary
}

const formatOpenHours = (schedule) => schedule
  .map(day => `${day.start}${day.end === day.start ? '' : ' - ' + day.end} ${day.times}`)
  .join(', ')

// This testable function is what I'd export
const reorder = (schedStr, day) => formatOpenHours(
  rotateSched(
    makeSched(schedStr).filter(day => day.times !== 'Closed'), 
    day
  )
)

// I wouldn't include this function.
// The dependence on current date makes it hard to test
const reorderSchedule = (schedStr) => reorder(schedStr, new Date().getDay())

// Demos

console.log(reorderSchedule(
  'Mon 3:00am - 9:00pm, Tue - Thu 5:30am - 9:30pm, Fri 7:15am - 10:00pm, Sat 8:00am - 3:00pm, Sun Closed'
))

console.log(reorder(
  'Mon 4:00am - 9:00pm, Tue 6:00am - 9:30pm, Wed - Fri 5:30am - 9:30pm, Sat 8:00am - 3:00pm, Sun Closed', 
  2
))

console.log(reorder(
  'Wed 5:30am - 9:30pm, Thu 6:30am - 4:00pm, Fri - Tue 8:00am - 3:00pm, Sun Closed',
  4
))

console.log(reorder(
  'Mon - Tue 5:30am - 9:30pm, Wed 6:30am - 4:00pm, Thu - Sat 8:00am - 3:00pm, Sun Closed',
  4
))

Это работает, создавая промежуточную структуру, массив с записями типа {start: 'Tue', end: Thu, times: '5:30am - 9:30pm'} или {start: 'Sun', end: 'Sun', times: 'Closed'}, а затем поворачивая это в зависимости от выбранного дня.

Я хотел бы отметить, что использование текущей даты в основной функции затрудняет тестирование.Я написал бы что-нибудь, что принимает день (reorder здесь), и использовал бы это как основную функцию, возможно, обернув это чем-то вроде reorderSchedule, если необходимо.Обратите внимание, как мало сделано в reorderSchedule;если этот маленький кусочек даты может быть передан вызывающей функции, тогда вам не нужен этот упаковщик, и код будет более тестируемым.

0 голосов
/ 20 сентября 2018

Следующее, вероятно, сработает, оно не удалит «Sun», не уверенный, хотите ли вы просто удалить этот день или потому, что оно закрыто.

const week = [
  'Sun',
  'Mon',
  'Tue',
  'Wed',
  'Thu',
  'Fri',
  'Sat',
];
const withDayPair = (item) => {
  //add [dayOneIndex, dayTwoIndex] to value
  const parts = item
    .split('-')
    .map((s) => s.trim())
    .map((s) => s.substr(0, 3));
  if (parts.length > 2) {
    //this value has day range (for example Mon - Wed)
    return [
      parts.slice(0, 2).map((p) => week.indexOf(p)),
      item,
    ];
  }
  return [[week.indexOf(parts[0]), -1], item]; //only one day, set second day to -1
};
const assignValue = (current) => ([[a, b], item]) => {
  //assign a value for sorting. If both values are smaller than current (earlier in the week)
  //  then add 10 to the index of the value in the array
  const val = a < current && b < current ? a + 10 : a;
  return [val, item];
};
const sortWith = (str, day) =>
  str
    .split(',')
    .map((s) => s.trim())
    .filter((s) => !s.startsWith('Sun'))//remove sunday
    //having a string representing days of week is not the best way to represent
    //  the data types used in your application
    .map(withDayPair)
    //now the values will be [[1,3],'Mon - Wed ....']
    .map(assignValue(week.indexOf(day))) //the [1,3] part is replaced with one number
    .sort(([a], [b]) => a - b) //sorting on that number
    .map(([_, item]) => item); //remove the number
const testVal =
  'Mon - Tue 5:30am - 9:30pm, Wed 6:30am - 4:00pm, Thu - Sat 8:00am - 3:00pm, Sun Closed';
console.log(
  //test for every day in the week
  ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
    .map(
      (day) =>
        `Day:${day} == ${sortWith(testVal, day).join(',')}`,
    )
    .join('\n'),
);
...