比较两个数组的相交值

时间:2018-07-31 15:37:54

标签: javascript arrays

我正在尝试使用JavaScript比较两个不同的数组并测试相交的值。

此阵列包含每周7天的可用性时间范围。在下面的availability数组中,每个键代表从星期日开始的一周中的一天。因此,键0 =星期日,键1 =星期一.....最大键数为6,即=星期六

var availability = [["8:30AM-12PM","2PM-6PM"],
["6:15AM-9:30AM","1PM-4PM","8PM-11:15PM"],[],["9AM-9PM"]];

下面的数组need1包含一周中特定日期(从星期日{key0}到星期六{key6}的任何地方)需要的时间范围。它使用与上述availability数组相同的键格式。 need1数组应在availability数组中列出的时间和日期内匹配。因此,在将need1availability进行比较时,应该找到一个匹配项。

var need1 = [["9AM-11:30AM","3PM-5PM"],[],[],["2PM-6:30PM"]]; //matches

下面的数组need2是不匹配的示例,因为需求时间范围不在availability数组中列出的时间和天数范围内。因此,将need2availability进行比较时,找不到匹配项。

var need2 = [["7:30AM-11:30AM"],[],[],["2PM-6:30PM", "8PM-10:30PM"]]; //does not match

我试图弄清楚如何比较这两个阵列以使需求范围与可用性范围相匹配。这意味着需求范围必须完全适合每天的可用性范围。比较时,我要查找的只是一个简单的true或false返回值。 true =匹配,false =不匹配。但是,我不知道如何有效地做到这一点。任何帮助将不胜感激!

此外,如果需要的话,如果可以比较它们,我可以用其他格式布置数组值。即使用日期值而不是字符串,或者使用24小时格式而不是12小时格式

1 个答案:

答案 0 :(得分:1)

我将在这里冒险,并采取与您刚开始时略有不同的方法,但这为您的基本问题提供了解决方案:可用时间与所需时间之间是否存在匹配?

在提供代码之前,这里有一些建议:
 1.在顶层使用对象,而不是数组。使用数组位置有意义是危险的。而是利用JavaScript对象文字的功能。
 2.分开开始和结束时间,不要将它们放在同一字符串中。
 3.利用本机Array方法的强大功能。

我提出了这些建议,并提供了以下代码段,因为看来您在解决问题的方式上仍有空间。

已更新 每个请求更改的假设。如果每个需要的开始时间/时隙在可用性对象中找到匹配的时隙,则仅返回给定日期的匹配。

类似以下内容应该可以将您带到您要去的地方。这将返回满足需求的对象。

/* structure your schedule as objects with arrays of objects of start/stop times */
const availability1 = {
  sunday: [
    {
      start: '08:30',
      stop: '12:00'
    },
    {
      start: '14:00',
      stop: '18:00'
    }
  ],
  monday: [{
    start: '06:25',
    stop: '11:45'
  }],
  wednesday: []
};

const need1 = {
  // will be matched, every needed time slot is within an availability slot
  // on the same day
  sunday: [ 
    {
      start: '09:45', // has a match
      stop: '12:00'
    },
    {
      start: '14:00', // has a match
      stop: '18:00'
    }

  ],
  monday: [ // will not be matched because...
    {
      start: '14:00', // has NO match
      stop: '16:00'
    },
    {
      start: '07:00', // has a match
      stop: '10:00'
    }
  ],
  tuesday: []
};

const getMinutes = (timeString) => {
  const timeParts = timeString.split(':');
  const hours = Number(timeParts[0]);
  const minutes = Number(timeParts[1]);
  const timeInMinutes = (hours * 60) + minutes;
  // console.log(`timeInMinutes: ${timeInMinutes}`);
  return timeInMinutes;
}

const isTimeMatch = (availabilityTime, needTime) => {
  
  const availStart = getMinutes(availabilityTime.start);
  const availStop = getMinutes(availabilityTime.stop);
  const needStart = getMinutes(needTime.start);
  const needStop = getMinutes(needTime.stop);
  
  console.log(`Availibility ${availabilityTime.start} (${availStart}) - ${availabilityTime.stop} (${availStop})`)
  console.log(`Need         ${needTime.start} (${needStart}) - ${needTime.stop} (${needStop})`)
  
  const startTimeMatch = availStart <= needStart;
  const stopTimeMatch = availStop >= needStop;
  
  const isMatch = startTimeMatch && stopTimeMatch;
  
  console.log(`is match: ${isMatch}`);
  return isMatch;
};

const compareDays = (availTimes, needTimes) => {
  return needTimes.map((needTime, i) => {
    
    const matches = availTimes.filter((availTime) => {
      return (isTimeMatch(availTime, needTime));
    });
    
    needTime.match = matches.length > 0;
    return needTime;
  }).filter((needTime, i, allNeedTimes) => {
    return (allNeedTimes.every((i) => i.match === true));
  });
}

function findMatches(availability, need) {
  
  const matches = Object.keys(availability).reduce((accumulator, day) => {
    
    if (availability[day] && need[day]) {
      console.log(`Possible matches found on ${day}`)
      const matches = compareDays(availability[day], need[day]);
      if (matches.length > 0) {
        accumulator[day] = matches;
      }
    }
    
    return accumulator;
    
  }, {});
  
  return (Object.keys(matches).length === 0) ?
    false : matches;
}

const matchedTimes = findMatches(availability1, need1);

if (matchedTimes) {
  console.log('The following needs match availability:');
  console.log(matchedTimes);
} else {
  console.log('No matches found');
}