如何用javascript创建一个基于已有数据的时隙数组

frebpwbc  于 2022-12-25  发布在  Java
关注(0)|答案(3)|浏览(128)

我正在为我的论文制作一个应用程序,我需要帮助解决一个具体的问题。让我先描述一下我想实现的功能。
在我的前端,我希望用户能够选择约会日期和时间。我考虑的方法是让他选择一个特定的日期。当他提交日期时,我希望以下面的方式生成一个可用时间段数组。
在我的数据库中,我有商店对象。每个商店都有一个约会数组。每个约会都有一个开始时间和结束时间。为了简单起见,我将每个约会的时间段设置为30分钟,例如,如果开始时间是14:00,结束时间是14:30。因此,在客户提交日期后,我用查询检索该特定日期的所有约会。同样为了简单起见,我的商店每天从8:00到21:00营业。
考虑到这一点,我想创建一个从8:00开始到21:00结束的数组,时间间隔为30分钟。但我想基于现有约会动态地创建这个数组,这意味着如果有一个约会从14:30开始,那么14:30 - 15:00的时间段将不会插入数组中。
我有一个粗糙的方法来做这件事,通过硬编码一个数组与所有时隙从8:00到9:00,然后数组动态约会时隙。然后我做了第三个数组过滤数组。我希望你的帮助,找到一种方法来做这件事更动态,以便有不同的开放时间在商店和不同的持续时间为每个约会的特点。
例如

const shop = {
    user: "fakeid123",
    title: "Barber Shop",
    description: "fake description",
    appointments: [{
            customername: "Kostas",
            start: "12:00",
            end: "12:30"
        },
        {
            customername: "Makis",
            start: "13:00",
            end: "13:30"
        },
        {
            customername: "Kostas",
            start: "14:00",
            end: "14:30"
        },
        {
            customername: "Kostas",
            start: "17:00",
            end: "17:30"
        }
    ],
    opens: "8:00",
    closes: "21:00"
};

根据上面的示例,数组应为:

[
    8: 00 - 8: 30
    8: 30 - 9: 00
    9: 00 - 9: 30
    9: 30 - 10: 00
    10: 30 - 11: 00
    11: 00 - 11: 30
    11: 30 - 12: 00
    12: 30 - 13: 00
    13: 30 - 14: 00
    14: 30 - 15: 00
    15: 00 - 15: 30
    ....
    16: 30 - 17: 00
    18: 00 - 18: 30
    ...
    20: 30 - 21: 00
]

时隙12:00-12:30 13:00-13:30 14:00-14:30 and 17:00-17:30不在阵列中
我这样做是为了向客户呈现一个下拉菜单,其中有可用的时间段可供选择。
开始和结束字段都是字符串,但都是时间格式。我如何迭代它们来创建数组呢?提前感谢

x6492ojm

x6492ojm1#

您将获得一个包含shop.opensshop.closes的时间范围。这是一个非常好的起点。您可以从中生成约会的其他时间范围。请这样考虑:

function generateAppointments(shop) {
    let appointments = [];
    let [hoursOp, minutesOp] = shop.opens.split(":"); //here you retrieve hours and minutes from your input string
    let [hoursCl, minutesCl] = shop.closes.split(":");
    let timeRange = Number.parseInt(hoursCl) - Number.parseInt(hoursOp);

    for (let i = 0; i < timeRange; i++) { //here you iterate for the whole range of hours you are given
        const appHourStart = Number.parseInt(hoursOp) + i;
        //here you check if the appointment is already booked
        //this is a lot of iteration, maybe you could find a better way to approach this
        //I made it what with came to my mind first
        const firstHalfBooked = shop.appointments.some(a => a.start === `${appHourStart}:00`); 
        const secondHalfBooked = shop.appointments.some(a => a.start === `${appHourStart}:30`);

        //here, you only create a array element if the spot isn't booked
        if(!firstHalfBooked) appointments.push(`${appHourStart}:00 - ${appHourStart}:30`);
        if(!secondHalfBooked) appointments.push(`${appHourStart}:30 - ${appHourStart+1}:00`);
    }

    console.log (appointments);
    return appointments;
}

希望这对你有帮助,你也能理解。
编辑:我保留了“开门”和“关门”字段的会议记录,这样你就可以预料到如果一家商店在8:30开门。

3phpmpom

3phpmpom2#

如果你有一个预留插槽的数组,并想得到一个可用插槽的数组,你需要一个所有插槽的数组无论如何(预留和可用的)。可以迭代所有插槽的数组,过滤掉另一个数组中的预留插槽,但这似乎不是很有效。
我想建议一个不同的方法:我有一个包含所有插槽的数组(默认情况下所有插槽都可以保留),然后使用一个简单的标志来指示插槽是否被保留。这将允许我们轻松地过滤原始数组,并获得一个包含空闲插槽或保留插槽的数组,这取决于您当前需要哪一个:

const shop = {
  user: "fakeid123",
  title: "Barber Shop",
  description: "fake description",
  opens: new Date('2010-01-01T08:00:00Z'),
  closes: new Date('2010-01-01T21:00:00Z'),
  slotDuration: 30 * 60000
};

shop.slots = generateSlots(shop.opens, shop.closes, shop.slotDuration);

reserveSlot("14:00-14:30", 'Customer 1');
reserveSlot("10:00-10:30", 'Customer 2');
reserveSlot("15:30-16:00", 'Customer 3');
reserveSlot("19:00-19:30", 'Customer 4');

console.log('RESERVED', getFilteredSlots(true));
console.log('AVAILABLE', getFilteredSlots(false));

function generateSlots(startTime, endTime, duration) {
  const allSlots = [];
  let slotStart = startTime;

  do {
    const slot = {
      start: slotStart,
      end: new Date(slotStart.getTime() + duration),
      reserved: false
    };
    slot.id = `${slot.start.getUTCHours()}:${slot.start.getUTCMinutes() || '00'}-${slot.end.getUTCHours()}:${slot.end.getUTCMinutes() || '00'}`;
    
    allSlots.push(slot);
    slotStart = slot.end;
  } while (slotStart < endTime);

  return allSlots;
}

function reserveSlot(slotId, customerName) {
  const result = shop.slots.map(slot => slot.id === slotId ? {...slot, customerName, reserved: true} : slot);
  shop.slots = result;
}

function getFilteredSlots(isReserved) {
  return shop.slots.filter(slot => slot.reserved === isReserved);
}

注:我还使用了日期类型而不是常规字符串,因为它更容易生成类似于generateSlots函数的列表。

z2acfund

z2acfund3#

最简单的方法是使用lodash库,它提供了许多数组函数。
您要查找的是_.xor
https://lodash.com/docs/4.17.15#xor

var timeTable = [];
for(let i = 8; i < 21; i++){
    timeTable.push(`${i}:00-${i}:30`);
    timeTable.push(`${i}:30-${i+1}:00`);
}

var myAppointments = ['8:00-8:30', '8:30-9:00', '9:00-9:30', '9:30-10:00', '10:00-10:30', '10:30-11:00', '11:00-11:30', '11:30-12:00', '12:30-13:00', '13:30-14:00', '14:30-15:00', '15:00-15:30', '15:30-16:00', '16:00-16:30', '16:30-17:00', '17:30-18:00', '18:00-18:30', '18:30-19:00', '19:00-19:30', '19:30-20:00', '20:00-20:30', '20:30-21:00'];

var myFreeTime = _.xor(myAppointments, timeTable);

myFreeTime.forEach((time) => document.getElementById("time").insertAdjacentHTML('beforeend', `${time}<br />`))

参见示例:https://jsfiddle.net/domus71/1n0voakc/
科斯季斯

相关问题