首页 > 解决方案 > 转换多个打开时间和减少单个打开时间的问题

问题描述

我试图解决这个问题。

问题:

给定一个 Days 数组和一个包含一周内一家商店的开始和结束时间的数据数组,找出该商店营业的天数/时间。

const daysArr = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];

// This is the times for *ONE STORE* in the entire week.
const data = [
    {
        startTime: '10:00am',
        endTime: '5:00pm',
        open: [true, true, false, false, false, false, false]
    },
    {
        startTime: '10:00am',
        endTime: '5:00pm',
        open: [false, false, true, false, false, false, false]
    }, 
    {
        startTime: '11:00am',
        endTime: '6:00pm',
        open: [false, false, false, true, false, false, true]
    } ];

解决方案应该是:

[“周一至周三上午 10:00 至下午 5:00”、“周四上午 11:00 至下午 6:00”、“周日上午 11:00 至下午 6:00”]

注意:可能存在间隙。例如,一家商店可能只在周四和周日营业(就像在示例中一样),在这种情况下,只返回他们营业的日子。

我的解决方案:

const daysArr = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
const data = [
{
    startTime: '10:00am',
    endTime: '5:00pm',
    open: [true, true, false, false, false, false, false]
},
{
    startTime: '10:00am',
    endTime: '5:00pm',
    open: [false, false, true, false, false, false, false]
}, 
{
    startTime: '11:00am',
    endTime: '6:00pm',
    open: [false, false, false, true, false, false, true]
}
];

function openStoreTimes(data) {
const store = {};

buildStore(store, data);

return printResult(store, data);

function printResult(store, data) {
    const values = Object.keys(store);
    const res = [];

    values.forEach(key => {
        const value = store[key]; // [true, true, true]
        res.push(...makeString(value, key));
    })

    return res;
}

function makeString(arr, key) {
    const res = [];
    let firstTrueidx=undefined;

    for(let i=0; i<arr.length; i++) {
        const isTrue = arr[i] === true ? true: false;
        
        if(isTrue) {
            if(firstTrueidx === undefined) firstTrueidx = i;
            if(arr[i+1] === false || !arr[i+1]) {
                let resultKey;

                if(firstTrueidx === i) {
                    resultKey = `${key} ${daysArr[firstTrueidx]}`;
                } else {
                    resultKey = `${key} ${daysArr[firstTrueidx]}-${daysArr[i]}`;
                }
                res.push(resultKey);
                firstTrueidx = undefined;
            }
        }
    }

    return res;
}

function buildStore(store, data) {
    data.forEach(each => {
        const {startTime, endTime, open} = each;
        const key = `${startTime}-${endTime}`;

        if(!store[key]) {
            store[key] = [...open];
        } else {
            makeTrueArray(store[key], open);
        }
    });
}

function makeTrueArray(a1, a2) {
    a2.forEach((each,i) => {
        if(each) a1[i] = true;
    });
}
}

console.log(openStoreTimes(data));
// [ '10:00am-5:00pm Monday-Wednesday', '11:00am-6:00pm Thursday', '11:00am-6:00pm Sunday' ]

问题:

我想出了以下解决方案,但是,我觉得这可以简化(我觉得我的解决方案过于复杂)。寻找巧妙的方法来解决这个问题。

标签: javascriptalgorithm

解决方案


我希望这是一种更简洁的方法来解决这个问题 -

const daysArr = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
const data = [
    {
        startTime: '10:00am',
        endTime: '5:00pm',
        open: [true, true, false, false, false, false, false]
    },
    {
        startTime: '10:00am',
        endTime: '5:00pm',
        open: [false, false, true, false, false, false, false]
    }, 
    {
        startTime: '11:00am',
        endTime: '6:00pm',
        open: [false, false, false, true, false, false, true]
    }
];

// get open time of the store on d'th day. Returns null if the shop is closed on 
// that day.
function getOpenTime(d){
    for(var i = 0; i < data.length; i++){
        if(data[i].open[d]){
            return {
                startTime: data[i].startTime,
                endTime: data[i].endTime
            }
        }
    }
    return null
}

// Helper function to format an `10:00am-5:00pm Monday-Wednesday` format, start and 
// end are index in the daysArr representing corresponding day of the week.
function dayFormatter(openTime, start, end) {
    return openTime.startTime + '-' + openTime.endTime + ' ' + daysArr[start] + (start == end ? '' : '-' + daysArr[end])
}

function getOpenDays(){
    result = []
    for(var i = 0; i < 7; i++){
        var iThDayOpenTime = getOpenTime(i);
        if(iThDayOpenTime != null){
            // If the shop is open on last day of the week, then no need to check any 
            // further, and the open time should be pushed to the result.
            if(i == 6){
                result.push(dayFormatter(iThDayOpenTime, i, i));
            }
            for(var j = i + 1; j < 7; j++){
                var jThDayOpenTime = getOpenTime(j);
                // If the opentime of j'th day does not match with i'th day, that
                // means all the days from i to j - 1, the shop is open on a same
                // time, which is equal to open time of i'th day
                if(jThDayOpenTime == null || iThDayOpenTime.startTime !== jThDayOpenTime.startTime || iThDayOpenTime.endTime !== jThDayOpenTime.endTime) {
                    result.push(dayFormatter(iThDayOpenTime, i, j - 1));
                    i = j - 1;
                    break;
                }
                // If the opentime of j'th day matches i'th day, there is only 
                // one case when j == 6, that means we have no other days to 
                // look at. So we know that all days from i to j, then shop is
                // open on a same time.
                else {
                    if(j == 6){
                        result.push(dayFormatter(iThDayOpenTime, i, j));
                        i = j;
                    }
                }
            }
        }
    }
    return result
}

console.log(getOpenDays());


推荐阅读