代码之家  ›  专栏  ›  技术社区  ›  Austin

比较两个数组的相交值

  •  0
  • Austin  · 技术社区  · 7 年前

    我试图使用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})。它使用与上面相同的密钥格式 可利用性 阵列。 需要1 数组应在 可利用性 阵列。所以在比较的时候 需要1 可利用性 应该找到匹配的。

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

    下面的数组 need2 是不匹配的示例,因为需要范围的时间超出了 可利用性 阵列。所以在比较的时候 需要2 可利用性 不应找到匹配项。

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

    我试图找出如何比较这两个数组,以匹配需求范围和可用性范围。这意味着需求范围必须完全符合每天的可用性范围。在比较时,我只需要一个简单的true或false返回值。 true =匹配和 false =不匹配。但是,我不知道如何有效地做到这一点。任何帮助都将不胜感激!

    另外,如果需要的话,我可以用不同的格式排列数组值,这样比较起来就更容易了。即使用日期值代替字符串,或使用24小时格式代替12小时格式

    1 回复  |  直到 7 年前
        1
  •  1
  •   Chad Moore    7 年前

    我要冒个险,采取一个与你刚开始时略有不同的方法,但这为你的基本问题提供了一个解决方案:可用时间和所需时间之间是否匹配?

    在我介绍代码之前,这里有一些建议:
    一。使用顶层的对象,而不是数组。使用有意义的数组位置是危险的。而是利用JavaScript对象文本的力量。
    2。分开你的开始和停止时间,不要把它们放在同一个字符串中。
    三。利用本机数组方法的能力。

    我提出这些建议,并提供以下代码片段,因为您似乎在如何处理问题方面有一些回旋余地。

    更新 根据请求更改假设。仅当每个所需的开始/时隙在availability对象中找到匹配的时隙时,才返回给定日期的match。

    像下面这样的东西应该能帮你找到你想去的地方。这将返回符合需要的对象。

    /* 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');
    }