skip to Main Content

I tried to do it but i am not able put condition. I want to find common slot.

  • first person test is available between 10 AM to 12PM
  • second person elton is available between 9 AM to 10:30 AM and 10:30
    AM to 11 AM
  • third person shawn is available between 10:30 AM to 11:00 AM

Hence common slot will be 10:30 AM to 11:00 AM

const input = [
  {
    email: '[email protected]',
    range: [
      {start: '10:00:00', end: '12:00:00' }
    ],
  },
  {
    email: '[email protected]',
    range: [
      {start: '09:00:00', end: '10:30:00'},
      {start: '10:30:00', end: '11:00:00' }
    ],
  },
  {
    email: '[email protected]',
    range: [
      {start: '10:30:00', end: '11:00:00' }
    ],
  },
];

output:

 [
      {start: '10:30:00', end: '11:00:00' }
  ]

second input example

const input = [
  {
    email: '[email protected]',
    range: [
      {start: '10:00:00', end: '12:00:00' }
    ],
  },
  {
    email: '[email protected]',
    range: [
      {start: '09:00:00', end: '10:30:00'},
      {start: '10:30:00', end: '11:00:00' },
      {start: '14:30:00', end: '15:00:00' }
    ],
  }
];

output:

[
 {start: '10:00:00', end: '11:00:00' }
]

third input example:

const input = [
  {
    email: '[email protected]',
    range: [
      {start: '10:00:00', end: '12:00:00' },
      {start: '14:30:00', end: '15:00:00' }
    ],
  },
  {
    email: '[email protected]',
    range: [
      {start: '09:00:00', end: '10:30:00'},
      {start: '10:30:00', end: '11:00:00' },
      {start: '14:30:00', end: '15:00:00' }
    ],
  }
];

output :

[
 {start: '10:00:00', end: '11:00:00' },
 {start: '14:30:00', end: '15:00:00' }
]

Code I have tried so far

function generateIntersectSlot(interviewerRange) {
  if (!interviewerRange.length) {
    return [];
  }
  for (let interviewer of interviewerRange) {
    for (let nextInterviewer of interviewerRange) {
      if (interviewer.email == nextInterviewer.email) {
        continue;
      }
      console.log(interviewer.email, 'interviewerSlot email')
      console.log(nextInterviewer.email, 'nextInterviewer email')
      const interviewerSlot = interviewer.range;
      const nextInterviewerSlot = nextInterviewer.range;
      for (let intSlot of interviewerSlot) {
        for (let nextIntSlot of nextInterviewerSlot) {

          console.log(intSlot, 'intSlot')
          console.log(nextIntSlot, 'nextIntSlot')
          // if(new Date(`${getDate}T${intSlot.start}`) >= new Date(`${getDate}T${nextIntSlot.start}`) ) {
          //   console.log(intSlot, 'asd')
          // } else {

          // } 


        }
      }
    }
  }
}

generateIntersectSlot(input);
<script>
  const input = [{
      email: '[email protected]',
      range: [{
        start: '10:00:00',
        end: '12:00:00'
      }],
    },
    {
      email: '[email protected]',
      range: [{
          start: '09:00:00',
          end: '10:30:00'
        },
        {
          start: '10:30:00',
          end: '11:00:00'
        }
      ],
    },
    {
      email: '[email protected]',
      range: [{
        start: '10:30:00',
        end: '11:00:00'
      }],
    },
  ];
</script>

3

Answers


  1. function getCommonSlots(inp){
        //last time to start will be start time for common slot
        const cStart = Math.max(...inp.map(e => e.range.map(el => new Date(`2024-01-01T${el.start}`).getTime())).flat(2));
    
        //first time to end will be end time for common slot
        const cEnd = Math.min(...inp.map(e => e.range.map(el => new Date(`2024-01-01T${el.end}`).getTime())).flat(2));
    
        return [{start: new Date(cStart).toLocaleTimeString('en-US', { hour12: false }),end: new Date(cEnd).toLocaleTimeString('en-US', { hour12: false })}]
    }
    

    try this one

    Login or Signup to reply.
  2. Find a common ranges for the two first interviewers, than compare them to the ranges of the next interviewer and repeat to the last interviewer:

    function generateIntersectSlot(arr) {
      if (arr.length < 2) {
        return [];
      }
      let prev = arr[0].range; // take the first interviewer's ranges as the first common ranges
      for(let i = 1; i < arr.length; i++){
        const curr = []; // collect the common ranges in an array
        for(const p of arr[i].range){
          for(const c of prev){
            if(c.start >= p.start && c.end <= p.end){ // current range is included in the previous, add it
              curr.push(c);
            }else if(p.start >= c.start && p.end <= c.end){ // previous range is included in the current, add it
              curr.push(p);
            }
          }
        }
        if(!curr.length) return [];
        prev = curr; // remember the current common ranges for the next comparison
      }
      
      return prev;
      
    }
    
    console.log(JSON.stringify(generateIntersectSlot(input)));
    console.log(JSON.stringify(generateIntersectSlot(input2)));
    <script>
      const input = [{
          email: '[email protected]',
          range: [{
            start: '10:00:00',
            end: '12:00:00'
          }],
        },
        {
          email: '[email protected]',
          range: [{
              start: '09:00:00',
              end: '10:30:00'
            },
            {
              start: '10:30:00',
              end: '11:00:00'
            }
          ],
        },
        {
          email: '[email protected]',
          range: [{
            start: '10:30:00',
            end: '11:00:00'
          }],
        },
      ];
    const input2 = [
      {
        email: '[email protected]',
        range: [
          {start: '10:00:00', end: '12:00:00' }
        ],
      },
      {
        email: '[email protected]',
        range: [
          {start: '09:00:00', end: '10:30:00'},
          {start: '10:30:00', end: '11:00:00' },
          {start: '14:30:00', end: '15:00:00' }
        ],
      }
    ];
    </script>
    Login or Signup to reply.
  3. We need to implement the function to intersect and union ranges and then we will need to loop the persons and ranges, find the intersections and then merge intersections that belong together:

    function max(first, second) {
        return (first > second) ? first : second;
    }
    
    function min(first, second) {
        return (first < second) ? first : second;
    }
    
    function merge(overlap, newOne) {
        for (let index = 0; index < overlap.length; index++) {
            let res = union(overlap[index], newOne);
            if (res) {
                overlap[index] = res;
                return;
            }
        }
        overlap.push(newOne);
    }
    
    function intersect(first, second) {
        if ((first.start > second.end) || (second.start > first.end)) {
            return null;
        }
        return {start: max(first.start, second.start), end: min(first.end, second.end)}
    }
    
    function union(first, second) {
        if ((first.start > second.end) || (second.start > first.end)) {
            return null;
        }
        return {start: min(first.start, second.start), end: max(first.end, second.end)}
    }
    
    function getOverlaps(persons) {
        let overlaps = persons[0].range;
        for (let i = 1; i < persons.length; i++) {
            let newOverlaps = [];
            for (let o of overlaps) {
                for (let o2 of persons[i].range) {
                    let intersection = intersect(o, o2);
                    if (intersection) {
                        merge(newOverlaps, intersection);
                    }
                }
            }
            if (newOverlaps.length === 0) return [];
            overlaps = newOverlaps;
        }
        return overlaps;
    }
    
    const input = [
    [
      {
        email: '[email protected]',
        range: [
          {start: '10:00:00', end: '12:00:00' }
        ],
      },
      {
        email: '[email protected]',
        range: [
          {start: '09:00:00', end: '10:30:00'},
          {start: '10:30:00', end: '11:00:00' }
        ],
      },
      {
        email: '[email protected]',
        range: [
          {start: '10:30:00', end: '11:00:00' }
        ],
      },
    ],
    [
      {
        email: '[email protected]',
        range: [
          {start: '10:00:00', end: '12:00:00' }
        ],
      },
      {
        email: '[email protected]',
        range: [
          {start: '09:00:00', end: '10:30:00'},
          {start: '10:30:00', end: '11:00:00' },
          {start: '14:30:00', end: '15:00:00' }
        ],
      }
    ],
     [ 
       {
         email: '[email protected]',
         range: [
           {start: '10:00:00', end: '12:00:00' },
           {start: '14:30:00', end: '15:00:00' }
         ],
       },
       {
         email: '[email protected]',
         range: [
           {start: '09:00:00', end: '10:30:00'},
           {start: '10:30:00', end: '11:00:00' },
           {start: '14:30:00', end: '15:00:00' }
         ],
       }
     ]
    ];
    
    console.log(getOverlaps(input[0]));
    console.log(getOverlaps(input[1]));
    console.log(getOverlaps(input[2]));
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search