0

I'm trying to use JavaScript to compare 2 different arrays and test for intersecting values.

This array contains ranges of times of availability for a 7 day week. In the availability array below each key represents a day of the week starting with Sunday. So key 0 = Sunday, key 1 = Monday..... maximum number of keys would be 6 which = Saturday

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

The below array need1 contains ranges of times of need for specific days throughout the week (anywhere from Sunday{key0} to Saturday{key6}). It uses the same key format as the above availability array. need1 array should match within the times and days listed in the availability array. So when comparing need1 to availability a match should be found.

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

The below array need2 is an example of an non-match, since the times of need ranges are outside the ranges of times and days listed in the availability array. So when comparing need2 to availability NO match should be found.

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

I'm trying to figure out how to compare these 2 arrays to match up the need ranges with the availability ranges. Meaning the need ranges have to completely fit inside the availability ranges for each day. All I'm looking for is a simple true or false returned value when comparing. true = match and false = NOT a match. However, I have no idea how to to efficiently do this. Any help would be appreciated!

Also, If need be I can lay out the array values in a different format if it would make comparing them easier. i.e. using date values instead of strings, or 24 hour format instead of 12 hour format

2
  • 1
    The first example should match within the availability array Match how? You need to state what you're matching on - if you're comparing array items with array items then this doesn't match (unless you mean the empty array), if you're comparing array items within arrays within the array, then that's different, but you need to explain more clearly Commented Jul 31, 2018 at 15:43
  • Since each index of the array is a day of week and you have to parse the semantics of the values of each string, the best would be to loop over all of the days of the week and then, for each day, check if the values from each array are compatible and, perhaps, write the results to a third array. You might start with for (const dayOfWeek of [0,1,2,3]) { const dayAvailability = availability[dayOfWeek]; const dayNeed = need1[dayOfWeek]; /* parse need and dayAvailability and dayNeed, compare, and write results to another array here */ } Commented Jul 31, 2018 at 15:52

1 Answer 1

1

I'm going to take a risk here and take a slightly different approach than you've started with, but which provides a solution to your basic question: are there any matches between the available times and the needed times?

Before I present code, here are some recommendations:
1. Use an Object at the top level, not an array. Using array positions as meaningful is dangerous. Instead utilize the power of JavaScript object literals.
2. Separate your start and stop times, do not put them in the same string.
3. Utilize the power of native Array methods.

I make these recommendations and provide the following code snippet as it seems that you have some wiggle room in how you approach the problem.

UPDATED Changed assumption per request. Only returns match for a given day, if every needed start/time slot finds a matched time slot in the availability object.

Something like the following should get you where you want to go. This will return an object of the matched needs.

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

Sign up to request clarification or add additional context in comments.

5 Comments

you are absolutely on the right track. Your coding abilities are way over my head! Is there any chance you can tweak your code to only show a true result only if all the items in the need array fall within the all the items in the availability array. If one time range in the need array is outside a range in the availability array then return false
Updated. See the answer above.
Thanks for the update but I'm still having a difficult time understanding your code. I've never used reduce, map, filter or match functions before. I know it's a lot to ask but is there any chance you can dumb your code down a tad?
I will not do that, at least not in this answer. At this point you're asking for free code work, that is not the intent of SO. At some point you will have to dive in and actually learn the language and how to read and write code. Your problem could be solved with plain ole' , dumbed-down for { .. } loops or .forEach() calls. Have you tried any of that on your own? BTW, all the methods I've used are documented here: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
I completely understand. I was able to figure out most of your code and it's been a huge help on my project. Thank you so much for putting in the time on this question!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.