JavaScript中的reduce方法

时间:2018-06-26 21:51:26

标签: javascript arrays

我认为这是一个更合理的问题,但它也涉及到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方法做到这一点,但不能做到这一点。

谢谢!

5 个答案:

答案 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)

您可以使用includesfilter包含可用小时数的数组并返回差值:

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));