我认为这是一个更合理的问题,但它也涉及到reduce方法(我认为这是解决此类问题的适当方法)。
这是我的3个数组:
const availableHours = [ 9, 10, 11, 12, 13, 14 ];
const exArr1 = [ 9, 10, 11, 12, 13, 14 ]
const exArr2 = [ 10, 11, 12, 13 ]
第一个代表所有可用时间。用户始终以任意配置预订彼此相邻的两个(例如9and10、13and14、10and11等)。现在,如果用户预订了所有三组(即9-10、11-12、13-14),我需要返回true。这意味着当天已满。但如果已预订f.ex。像10-11和12-13一样,它也应该返回true,因为那些尚未预订的小时数(9和14)因为是一个小时而无法预订。两个示例数组都应返回true。
您可以帮忙吗?我试图用reduce方法做到这一点,但不能做到这一点。
谢谢!
答案 0 :(得分:1)
此答案不使用Array.prototype.reduce
,但我认为它可以解决您的问题。
它的工作原理是首先从可用时间列表中删除所有预订时间。假设天数预订是正确的(连续预订每小时对)。
然后迭代剩余的可用小时,并检查连续的小时对。如果未找到,则认为当天已满。如果找到一个或多个,则表示该书已满。
const available = [ 9, 10, 11, 12, 13, 14 ];
const day1 = [ 9, 10, 11, 12, 13, 14 ];
const day2 = [ 10, 11, 12, 13 ];
const day3 = [ 9, 10, 12, 13 ];
const day4 = [ 9, 10 ];
function isFullyBooked(day, available) {
const remaining = available.filter((hour) => ! day.includes(hour));
for (let i = 0; i < remaining.length; i++) {
if (remaining[i] + 1 === remaining[i + 1]) return false;
}
return true;
}
console.log(isFullyBooked(day1, available));
console.log(isFullyBooked(day2, available));
console.log(isFullyBooked(day3, available));
console.log(isFullyBooked(day4, available));
答案 1 :(得分:0)
您可以使用includes和filter包含可用小时数的数组并返回差值:
const availableHours = [9, 10, 11, 12, 13, 14];
const exArr1 = [9, 10, 11, 12, 13, 14]
const exArr2 = [10, 11, 12, 13]
const check = (arr, avail) => {
const diff = avail.filter(e => !arr.includes(e))
if (diff.length === 0)
console.log('all hours are booked')
else
console.log('unbooked hours : ', diff)
return true
}
console.log(check(exArr1, availableHours))
console.log(check(exArr2, availableHours))
答案 2 :(得分:0)
您可以使用过滤器来查找所需的块,例如:
const availableHours = [ 9, 10, 11, 12, 13, 14 ];
const exArr1 = [ 9, 10, 11, 12, 13, 14 ]
const exArr2 = [ 11, 12 ]
function getStartTimes(arr, taken) {
return arr.filter((item, index) => index != availableHours.length -1
&& !taken.includes(item)
&& !taken.includes(availableHours[index +1])
)
}
console.log(getStartTimes(availableHours, exArr1))
console.log(getStartTimes(availableHours, exArr2))
返回的数组将是小时,可以开始2小时块。如果只想要true或false,则可以测试此数组的长度。
这还具有以下优点:如果像[9, 12, 13, 14]
这样保留一小时的代码块,它仍然可以工作(结果应该显示两个小时的代码块,从10开始可用)
答案 3 :(得分:0)
如果您想使用Array.prototype.reduce
这是一种以更多功能定义的解决方案。
const fullyBooked = (available, booked) =>
!booked.reduce(
// reducer zeros out booked hours from inverted array
(accumulator, currentValue) => (accumulator[currentValue] = 0, accumulator),
// initial value is available times inverted into an array of 1's and 0's 1 if available
available.reduce(
(accumulator2, currentValue2) => (accumulator2[currentValue2] = 1, accumulator2),
new Array(25).fill(0)
)
).some(
// not fully booked if two hours are sequentially available
(value, index, array) => value && array[index+1]
);
console.log(fullyBooked([9, 10, 11, 12, 13, 14], [9, 10, 11, 12, 13, 14]));
console.log(fullyBooked([9, 10, 11, 12, 13, 14], [9, 10, 11, 12, 13]));
console.log(fullyBooked([9, 10, 11, 12, 13, 14], [10, 11, 12, 13, 14]));
console.log(fullyBooked([9, 10, 11, 12, 13, 14], [9, 10, 13, 14]));
console.log(fullyBooked([9, 10, 11, 12, 13, 14], [9, 11]));
答案 4 :(得分:0)
这两种方法都不使用reduce,但是它可以正确过滤内容,我特别喜欢将函数分离出来以获取更具可读性/分段的代码,而不是将所有逻辑都放入一个reduce中。
const allAvailable = {
9: true,
10: true,
11: true,
12: true,
13: true,
14: true,
};
const exArr1 = [ 9, 10, 11, 12, 13, 14 ];
const exArr2 = [ 10, 11, 12, 13 ];
const exArr3 = [ 10, 11 ];
function remainingHours(hours) {
const stillAvailable = Object.assign({}, allAvailable);
hours.forEach(hour => {
delete stillAvailable[hour];
});
return Object.keys(stillAvailable);
}
function hasConsecutive(hoursAvailable) {
if (hoursAvailable.length < 2) {
return false;
}
return hoursAvailable.some((hour, index) => {
if (index < hoursAvailable.length - 1) {
return +hour + 1 === +hoursAvailable[index + 1];
}
});
}
function isBooked(hours) {
return !hasConsecutive(remainingHours(hours));
}
console.log(isBooked(exArr1));
console.log(isBooked(exArr2));
console.log(isBooked(exArr3));