我有一个接收小时数组(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 有空闲时间。我希望这个解释有帮助。
我已经尝试了几个月,但一直没有得到好的结果。
好吧,看来您首先需要两个函数来在“人类可读”的时间表示和分钟数之间进行转换:
// 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
是时隙持续时间(以分钟为单位)。
您可以从反向迭代输入数组中受益,以便您可以跟踪哪个是即将到来的不空闲的插槽。
此外,由于您现在想要使用 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);
}
}