JavaScript 中与时间相关的练习

问题描述 投票:0回答:2

我有一个接收小时数组(hoursArray)和数字变量(分钟)的函数。 hourArray 是理发师时间表的可用时间。持续时间是客户预订的服务(美发沙龙)的持续时间。

当前代码返回另一个数组,其中包含根据变量“分钟”可用的hoursArray的小时数,也就是说:如果数组hoursArray是:

const hoursArray = [
    "09:00",
    "11:00",
    "11:30",
    "12:00",
    "13:00",
    "14:00",
    "14:30",
    "15:00",
    "15:30",
    "16:00",
];

分钟是:

minutes = 30

函数返回:

[ '09:00', '11:00', '11:30', '12:00', '13:00', '14:00', '14:30', '15:00', '15:30', '16:00' ]

为什么?

本例中的 arrayHours 是 30 分钟的间隔。如果 arrayHours 以 09:00、11:00 开始,则表示 09:30、10:00 和 10:30 已被保留。所以在返回数组中,这个时间不会出现,只有09:00和11:00。这是所有数组的逻辑。

如果

minutes = 60
具有相同的hoursArray,则函数返回:

[ '11:00', '11:30', '14:00', '14:30', '15:00', '15:30' ]

对此进行建模的代码是:

function getAvailableHours(hours: string[], minutes: number): string[] {
    const availableHours: string[] = [];

    for (let i = 0; i < hours.length - 1; i++) {
        const currentHour = hours[i];
        const nextHour = hours[i + 1];

        const [hour1, minute1] = currentHour.split(":").map(Number);
        const [hour2, minute2] = nextHour.split(":").map(Number);

        const totalMinutes1 = hour1 * 60 + minute1;
        const totalMinutes2 = hour2 * 60 + minute2;
        const timeDifference = totalMinutes2 - totalMinutes1;

        if (minutes === 60) {
            if (timeDifference >= minutes) { } else {
                availableHours.push(currentHour);
            }
        }

        if (minutes === 30) {
            availableHours.push(currentHour);
        }
    }

    if (minutes === 30) {
        availableHours.push(hours[hours.length - 1]);
    }
    return availableHours;
}

但是现在,我需要其他功能,我需要该函数执行相同的操作,但在“分钟”变量中包含更多值(15 分钟、30 分钟、45 分钟或 60 分钟)

其他使用案例:

const hoursArray = [
    "09:00",
    "09:30",
    "10:30",
    "11:00",
    "11:30",
    "12:00",
    "13:00",
    "14:00",
    "14:30",
    "15:00",
    "15:30",
    "16:00",
];

minutes = 60

结果:

[ '09:00', '10:30', '11:00', '11:30', '14:00', '14:30', '15:00', '15:30' ]

为什么?

如果分钟是 60,这就是为什么这项服务我们需要 60 分钟。这意味着返回中会显示 09:00,因为 hoursArray 有:09:00、09:30 和 10:00,因为 hoursArray 的间隔为 30 分钟,我们知道从 09:30 开始还有 60 分钟。在 09:30 的情况下,您可以注意到 in 没有出现在返回中,因为我们没有提前 60 分钟 09:30

其他情况:

 minutes = 30

结果:

[ '09:00', '09:30', '10:30', '11:00', '11:30', '12:00', '13:00', '14:00', '14:30', '15:00', '15:30', '16:00' ]

如果您复制代码并在 IDE 中执行它,您可以使用 hoursArray 中的其他时间对其他情况进行测试,并在“分钟”变量上更改 60 到 30 之间,以便更好地查看操作。

我需要该函数允许返回一个数组,但也允许分钟 = 45 和分钟 = 60,因为目前它不适用于此值。

这里有一个例子,说明结果和输入数据应该如何:

在该函数的新版本中,hoursArray 中的小时数必须以 15 分钟为间隔,例如:

hoursArray = ["09:00","09:15","09:30","10:00","10:30","10:45","11:00","11:15","11:45","12:15","12:30"]

如果没有出现一小时,是因为这15分钟已被预订。在这种情况下,例如“10:15”不可用,这是因为有人在 10:15 预订了一项 15 分钟的服务。

使用这个小时数组,例如

duration = 45
分钟,结果应该是:

["09:00", "10:30", "10:45"]

但是,另一方面,如果

duration = 15
,数组应该与hoursArray相同。 如果
duration = 30
可用时间应为:

["09:00", "09:15", "10:30", "10:45", "11:00", "12:15"]

在这种情况下,例如 09:15 可用,因为我们有 30 分钟的空闲时间:下一个小时是 09:30,我们有 15 分钟的间隔,所以我们从 09:15 到 09:45 有空闲时间。我希望这个解释有帮助。

我已经尝试了几个月,但一直没有得到好的结果。

javascript arrays time
2个回答
0
投票

好吧,看来您首先需要两个函数来在“人类可读”的时间表示和分钟数之间进行转换:

 // timeToMins('09:30') -> 570
 function timeToMins(time: string): number { ... }
 // minsToTime(570) -> '9:30'
 function minsToTime(mins: number): string { ... }

现在,假设您的输入是已预订的具有一定持续时间的时段的开始时间列表,您可以使用如下方式计算可用时段的列表:

  let bookedMins = input.map(timeToMins)
  let availMins = []

  for (
        let mins = timeToMins(OPEN_TIME); 
        mins < timeToMins(CLOSE_TIME);
        mins += duration
  )
     if (!bookedMins.includes(mins))
          availMins.push(mins)

  return availMins.map(minsToTime)

其中

OPEN/CLOSE_TIME
是字符串常量,
duration
是时隙持续时间(以分钟为单位)。


0
投票

您可以从反向迭代输入数组中受益,以便您可以跟踪哪个是即将到来的空闲的插槽。

此外,由于您现在想要使用 15 分钟而不是 60 分钟的块,因此我建议将此信息定义为函数的额外参数。我们称其为

unit

下面是一个可能的实现。驱动程序代码将所有示例定义为测试用例,然后执行并验证它们:

function getAvailableHours(hours, unit, duration) {
    let occupied;
    return hours.toReversed()
         .map((s, rev) => [s, s.split(":").reduce((h, m) => h * 60 + +m)])
         .filter(([, m], i, rev) => {
            if (rev[i-1]?.[1] !== m + unit) occupied = m + unit;
            return occupied >= m + duration;
         }).map(([s]) => s)
         .reverse();
}

// Define test cases
const tests = [{ 
    hours: ["09:00","11:00","11:30","12:00","13:00","14:00","14:30","15:00","15:30","16:00"],
    unit: 30,
    duration: 30,
    expected: ["09:00","11:00","11:30","12:00","13:00","14:00","14:30","15:00","15:30","16:00"]
}, {
    hours: ["09:00","11:00","11:30","12:00","13:00","14:00","14:30","15:00","15:30","16:00"], 
    unit: 30,
    duration: 60,
    expected: ["11:00","11:30","14:00","14:30","15:00","15:30"]
}, {
    hours: ["09:00","09:30","10:30","11:00","11:30","12:00","13:00","14:00","14:30","15:00","15:30","16:00"], 
    unit: 30,
    duration: 60,
    expected: [ '09:00', '10:30', '11:00', '11:30', '14:00', '14:30', '15:00', '15:30' ]
}, {
    hours: ["09:00","09:30","10:30","11:00","11:30","12:00","13:00","14:00","14:30","15:00","15:30","16:00"], 
    unit: 30,
    duration: 30,
    expected: [ '09:00', '09:30', '10:30', '11:00', '11:30', '12:00', '13:00', '14:00', '14:30', '15:00', '15:30', '16:00' ]
}, {
    hours: ["09:00","09:15","09:30","10:00","10:30","10:45","11:00","11:15","11:45","12:15","12:30"],
    unit: 15, // !!
    duration: 45,
    expected: ["09:00","10:30","10:45"]
}, {
    hours: ["09:00","09:15","09:30","10:00","10:30","10:45","11:00","11:15","11:45","12:15","12:30"],
    unit: 15,
    duration: 15,
    expected: ["09:00","09:15","09:30","10:00","10:30","10:45","11:00","11:15","11:45","12:15","12:30"]
}, {
    hours: ["09:00","09:15","09:30","10:00","10:30","10:45","11:00","11:15","11:45","12:15","12:30"],
    unit: 15,
    duration: 30,
    expected: ["09:00","09:15","10:30","10:45","11:00","12:15"]
}];

// Execute test cases
for (const {hours, unit, duration, expected} of tests) {
    const res = getAvailableHours(hours, unit, duration);
    console.log("------------------------------------------");
    console.log("hours:", ...hours);
    console.log("unit:", unit, "  duration:", duration);
    console.log("result:", ...res);
    if (JSON.stringify(res) !== JSON.stringify(expected)) {
        throw "Expected " + JSON.stringify(expected);
    }
}

© www.soinside.com 2019 - 2024. All rights reserved.