Combine Available TimeSlots of all Rooms

Lets say I have three rooms with individual available time slots and total time slots

total time slots:

["09:00-10:00","10:00-11:00", "11:00-12:00",  "12:00-13:00", "13:00-14:00", "14:00-15:00"]

Room1 is available for

[ "10:00-11:00", "11:00-12:00",  "12:00-13:00"]

Room2 is available for

[ "11:00-12:00",  "12:00-13:00", "13:00-14:00"]

Room3 is available for

[ "12:00-13:00", "13:00-14:00", "14:00-15:00"]

I want to filter out available time slots with room number, so I want my output as this.

[{
    slot: "09:00-10:00",
    available: false,
    space : []
},{
    slot: "10:00-11:00",
    available: true,
    space : ["room1"]
},{
    slot: "11:00-12:00",
    available: true,
    space : ["room1", "room2"]
},{
    slot: "12:00-13:00",
    available: true,
    space : ["room1", "room2", "room3"]
},{
    slot: "13:00-14:00",
    available: true,
    space : ["room2", "room3"]
},{
    slot: "14:00-15:00",
    available: true,
    space : ["room3"]
}]

What I tried:

const ts = ['10:00-10:30','10:30-11:00','11:00-11:30','11:30-12:00','12:00-12:30','12:30-13:00','13:00-13:30','13:30-14:00','14:00-14:30','14:30-15:00','15:00-15:30','15:30-16:00'];

const room1 = ["11:00-11:30", "13:05-13:35", "14:05-14:15"];

const avail = (ts, booked) =>
	ts.map(item => {
		const[start, end] = item.split('-');
		const isBooked = booked
			.map(item => item.split('-'))
			.some(([bookedStart, bookedEnd]) =>
				(start >= bookedStart && start < bookedEnd) ||
				(end > bookedStart && end <= bookedEnd) ||
				(bookedStart >= start && bookedStart < end));
		return {slot: `${start}-${end}`, isBooked};
	})
    


console.log(avail(ts,room1));
.as-console-wrapper {min-height: 100%}

Answers:

Answer

I have try my best to make it workable. Please check this if meets your requirement or not.

const ts = ['10:00-10:30','10:30-11:00','11:00-11:30','11:30-12:00','12:00-12:30','12:30-13:00','13:00-13:30','13:30-14:00','14:00-14:30','14:30-15:00','15:00-15:30','15:30-16:00'];

let rooms = {"room100":["11:00-11:30", "13:05-13:35", "14:05-14:15"],"room200":[ "11:00-12:00",  "12:00-13:00", "13:00-14:00"],"room300":[ "12:00-13:00", "13:00-14:00", "14:00-15:00"]};
var final = [];
const avail = (ts, room) =>
	ts.map(item => {
		const[start, end] = item.split('-');
    let slot = [];
    
  for(var key in room)
        {
    	let avilable = room[key]
			.map(item => item.split('-'))
			.some(([bookedStart, bookedEnd]) =>
				(start >= bookedStart && start < bookedEnd) ||
				(end > bookedStart && end <= bookedEnd) ||
				(bookedStart >= start && bookedStart < end));
       slot = avilable == false ? [...slot] : [...slot,key];
       console.log()
    }
    const isBooked = slot.length > 0 ? true :false;
    final.push({"slot":`${start}-${end}`, "available": isBooked, "space": slot })
    //console.log(`${start}-${end}`,isBooked, slot);
	})
  
avail(ts,rooms);

console.log(final)
.as-console-wrapper {min-height: 100%}

Answer

You can do this with filter and Object.entries (given that you have a rooms object). The idea is that for each time slot in the ts array, you want to find (filter) rooms that have an availability that falls in that time slot.

I also recommend abstracting the logic for checking whether a time overlaps a time slot to another function so you can test it separately:

const ts = ['10:00-10:30','10:30-11:00','11:00-11:30','11:30-12:00','12:00-12:30','12:30-13:00','13:00-13:30','13:30-14:00','14:00-14:30','14:30-15:00','15:00-15:30','15:30-16:00'];
const rooms = {
  'room1': ["11:00-11:30", "13:05-13:35", "14:05-14:15"],
  'room2': [ "11:00-12:00",  "12:00-13:00", "13:00-14:00"],
  'room3': [ "12:00-13:00", "13:00-14:00", "14:00-15:00"]
};

const overlaps = (slot, booking) => {
  const [start, end] = slot.split('-');
  const [bookedStart, bookedEnd] = booking.split('-');
  return (start >= bookedStart && start < bookedEnd) ||
		 (end > bookedStart && end <= bookedEnd) ||
		 (bookedStart >= start && bookedStart < end);
};

const res = ts.map(slot => {
  const space = Object.entries(rooms)
    .filter(([_, availableSlots]) => availableSlots.some(roomSlot => overlaps(slot, roomSlot)))
    .map(([room, _]) => room);
  return {slot, space, available: space.length > 0};
});

console.log(res);

Answer

You could take some nested iterating structures and check if a room is available in the wanted slot.

var slots = [ '10:00-11:00',
  '10:15-11:15',
  '10:30-11:30',
  '10:45-11:45',
  '11:00-12:00' ],
    rooms = { '5d396fd3f0315c3f56b255d4-5d396fe2f0315c3f56b25a79': [],
  '5d396fa0f0315c3f56b245d6': [ '11:00-12:00' ] },
    roomEntries = Object.entries(rooms),
    result = slots.map(slot => {
        var [sStart, sEnd] = slot.split('-'),
            space = roomEntries
                .filter(([room, a]) => a.some(available => {
                    var [aStart, aEnd] = available.split('-');
                    return (sStart >= aStart && sEnd <= aEnd || sStart <= aStart && sEnd > aStart || sStart < aEnd && sEnd >= aEnd);
                }))
                .map(([k]) => k);
        return { slot, available: !!space.length, space };
    });

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.