从现在开始查找最近的空闲时间段,如果给定了某些工作日的空闲时间段。

huangapple go评论59阅读模式
英文:

Finding the nearest free time slot from now if free slots in some working days are given

问题

我有一个函数,它接受一个对象数组作为参数,每个对象包含一个表示星期几的 'day' 键(用于表示星期几)和一个表示可用时间段的字符串数组的 'freeSlots' 键(时间段格式为 'h:mm a')。该函数的目标是找到并返回从当前日期和时间开始的最近有效的空闲时间段。如果当前周没有最近的时间段可用,则应返回 "等待下周"。然而,在星期二搜索最近的时间段时,该函数返回了一个意外的结果。

function findNearestFreeSlot(slotsArray) {
    const currentDate = moment();
    let nearestDayDiff = Infinity;
    let nearestSlot = null;

    for (const daySlots of slotsArray) {
        const { day, freeSlots } = daySlots;

        for (const slot of freeSlots) {
            const slotDateTime = moment(slot, 'h:mm a').day(day);

            // 检查时间段是否在当前日期之后或与当前日期相同
            if (slotDateTime.isSameOrAfter(currentDate)) {
                const diffDays = Math.abs(currentDate.diff(slotDateTime, 'days'));

                if (diffDays < nearestDayDiff || (diffDays === nearestDayDiff && slotDateTime.isBefore(nearestSlot))) {
                    nearestDayDiff = diffDays;
                    nearestSlot = slotDateTime;
                }
            }
        }
    }

    return nearestSlot ? nearestSlot.format('ddd, h:mm a') : "等待下周";
}

我使用以下数组来测试上述函数:

const freeSlotsArray = [
    {
        day: 'wed',
        freeSlots: ['12:00 pm', '1:00 pm', '1:30 pm', '2:30 pm', '3:00 pm', '3:30 pm', '4:30 pm', '5:00 pm', '6:30 pm', '7:00 pm']
    },
    {
        day: 'sat',
        freeSlots: ['7:00 am', '7:30 am', '8:00 am', '9:00 am', '10:00 am', '10:30 am', '11:30 am', '12:00 pm', '12:30 pm']
    },
    {
        day: 'thu',
        freeSlots: ['12:00 pm', '1:00 pm', '1:30 pm', '2:30 pm', '4:00 pm', '5:30 pm', '6:30 pm', '7:00 pm']
    },
    {
        day: 'mon',
        freeSlots: ['4:00 pm', '4:30 pm', '6:00 pm', '6:30 pm', '7:30 pm', '8:00 pm', '8:30 pm', '9:30 pm']
    },
];

const nearestFreeSlot = findNearestFreeSlot(freeSlotsArray);
console.log(nearestFreeSlot);

在星期二搜索最近的时间段时,预期输出应为 "Wed, 12:00 pm" 而不是 "Wed, 4:30 pm"。

英文:

I have a function that takes an array of objects, where each object contains a 'day' key (representing the day of the week) and an 'freeSlots' key (representing an array of available time slots as strings in 'h:mm a' format). The function aims to find and return the nearest valid free time slot from the current date and time. If no nearest slot is available for the current week, it should return "wait for next week." However, when searching for the nearest slot on Tuesday, the function is returning an unexpected result.

function findNearestFreeSlot(slotsArray) {
    const currentDate = moment();
    let nearestDayDiff = Infinity;
    let nearestSlot = null;

    for (const daySlots of slotsArray) {
        const { day, freeSlots } = daySlots;

        for (const slot of freeSlots) {
            const slotDateTime = moment(slot, &#39;h:mm a&#39;).day(day);

            // Check if the slot is on or after the current date
            if (slotDateTime.isSameOrAfter(currentDate)) {
                const diffDays = Math.abs(currentDate.diff(slotDateTime, &#39;days&#39;));

                if (diffDays &lt; nearestDayDiff || (diffDays === nearestDayDiff &amp;&amp; slotDateTime.isBefore(nearestSlot))) {
                    nearestDayDiff = diffDays;
                    nearestSlot = slotDateTime;
                }
            }
        }
    }

    return nearestSlot ? nearestSlot.format(&#39;ddd, h:mm a&#39;) : &quot;wait for next week&quot;;
}

I have used this array for testing the above function

const freeSlotsArray = [
    {
        day: &#39;wed&#39;,
        freeSlots: [&#39;12:00 pm&#39;, &#39;1:00 pm&#39;, &#39;1:30 pm&#39;, &#39;2:30 pm&#39;, &#39;3:00 pm&#39;, &#39;3:30 pm&#39;, &#39;4:30 pm&#39;, &#39;5:00 pm&#39;, &#39;6:30 pm&#39;, &#39;7:00 pm&#39;]
    },
    {
        day: &#39;sat&#39;,
        freeSlots: [&#39;7:00 am&#39;, &#39;7:30 am&#39;, &#39;8:00 am&#39;, &#39;9:00 am&#39;, &#39;10:00 am&#39;, &#39;10:30 am&#39;, &#39;11:30 am&#39;, &#39;12:00 pm&#39;, &#39;12:30 pm&#39;]
    },
    {
        day: &#39;thu&#39;,
        freeSlots: [&#39;12:00 pm&#39;, &#39;1:00 pm&#39;, &#39;1:30 pm&#39;, &#39;2:30 pm&#39;, &#39;4:00 pm&#39;, &#39;5:30 pm&#39;, &#39;6:30 pm&#39;, &#39;7:00 pm&#39;]
    },
    {
        day: &#39;mon&#39;,
        freeSlots: [&#39;4:00 pm&#39;, &#39;4:30 pm&#39;, &#39;6:00 pm&#39;, &#39;6:30 pm&#39;, &#39;7:30 pm&#39;, &#39;8:00 pm&#39;, &#39;8:30 pm&#39;, &#39;9:30 pm&#39;]
    },
];


const nearestFreeSlot = findNearestFreeSlot(freeSlotsArray);
console.log(nearestFreeSlot);

When searching for the nearest slot on Tuesday, the expected output should be "Wed, 12:00 pm" instead of "Wed, 4:30 pm".

答案1

得分: 0

问题在于你向.day()传递了一个错误的参数,应该传递一个从0到6的数字(或者是星期的全名,但我不确定这种替代方法的效果如何)。

下面是一个更简洁的函数和你的正确函数。

const fakeDay = 2; // 2代表星期二,你可以根据需要修改为其他日期,星期日:0,星期一:1,星期二:2,星期三:3,星期四:4,星期五:5,星期六:6

function findNearestFreeSlot(slotsArray) {
  const currentDate = moment().day(fakeDay);
  let nearestDayDiff = Infinity;
  let nearestSlot = null;

  const indexDays = { sun: 0, mon: 1, tue: 2, wed: 3, thu: 4, fri: 5, sat: 6 }; // 添加这个索引数字:星期几

  for (const daySlots of slotsArray) {
    const { day, freeSlots } = daySlots;

    for (const slot of freeSlots) {
      const slotDateTime = moment(slot, 'h:mm a').day(indexDays[day]); // <---- 使用索引

      // 检查时间是否在当前日期之后或者与当前日期相同
      if (slotDateTime.isSameOrAfter(currentDate)) {
        const diffDays = Math.abs(currentDate.diff(slotDateTime, 'days'));

        if (diffDays < nearestDayDiff || (diffDays === nearestDayDiff && slotDateTime.isBefore(nearestSlot))) {
          nearestDayDiff = diffDays;
          nearestSlot = slotDateTime;
        }
      }
    }
  }

  return nearestSlot ? nearestSlot.format('ddd, h:mm a') : "等待下周";
}


function findNearestFreeSlotMyTry(slotsArray) {
  const currentDate = moment().day(fakeDay);

  const indexDays = { sun: 0, mon: 1, tue: 2, wed: 3, thu: 4, fri: 5, sat: 6 };

  const listSlots = slotsArray
    .reduce((prev, { day, freeSlots }) => { // 将自由时间段的对象转换为带有差异的数组
      for (const slot of freeSlots) {
        const dateSlot = moment(slot, 'h:mm a').day(indexDays[day]);
        const diff = dateSlot.diff(currentDate);
        if (diff >= 0) prev.push({ diff, date: dateSlot.format('ddd, h:mm a') }); // 只获取未来的时间段
      }
      return prev;
    }, [])
    .sort((a, b) => a.diff < b.diff ? -1 : 1); // 按照差异排序数组,从最近到最远

  return listSlots?.[0]?.date || '等待下周'; // 返回日期或字符串
}

const freeSlotsArray = [
  {
    day: 'wed',
    freeSlots: ['12:00 pm', '1:00 pm', '1:30 pm', '2:30 pm', '3:00 pm', '3:30 pm', '4:30 pm', '5:00 pm', '6:30 pm', '7:00 pm']
  },
  {
    day: 'sat',
    freeSlots: ['7:00 am', '7:30 am', '8:00 am', '9:00 am', '10:00 am', '10:30 am', '11:30 am', '12:00 pm', '12:30 pm']
  },
  {
    day: 'thu',
    freeSlots: ['12:00 pm', '1:00 pm', '1:30 pm', '2:30 pm', '4:00 pm', '5:30 pm', '6:30 pm', '7:00 pm']
  },
  {
    day: 'mon',
    freeSlots: ['4:00 pm', '4:30 pm', '6:00 pm', '6:30 pm', '7:30 pm', '8:00 pm', '8:30 pm', '9:30 pm']
  }
];

const nearestFreeSlot = findNearestFreeSlot(freeSlotsArray);
console.log('----- > ', nearestFreeSlot);

const nearestFreeSlotMyTry = findNearestFreeSlotMyTry(freeSlotsArray);
console.log('----- > ', nearestFreeSlotMyTry);

请确保在代码中引入了Moment.js库。

英文:

The problem is that you pass a wrong parameter to .day(), pass it a number ranging from 0 to 6 (or the full name of the day, but I'm not sure how well this alternative works).

Below I put a more compact function and your correct one.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const fakeDay = 2; // 2 is Tuesday, change it for simulate a day sun: 0, mon: 1, tue: 2, wed: 3, thu: 4, fri: 5, sat: 6
function findNearestFreeSlot(slotsArray) {
const currentDate = moment().day(fakeDay);
let nearestDayDiff = Infinity;
let nearestSlot = null;
const indexDays = { sun: 0, mon: 1, tue: 2, wed: 3, thu: 4, fri: 5, sat: 6 }; // Add this index number: day
for (const daySlots of slotsArray) {
const { day, freeSlots } = daySlots;
for (const slot of freeSlots) {
const slotDateTime = moment(slot, &#39;h:mm a&#39;).day(indexDays[day]); // &lt;---- use the index
// Check if the slot is on or after the current date
if (slotDateTime.isSameOrAfter(currentDate)) {
const diffDays = Math.abs(currentDate.diff(slotDateTime, &#39;days&#39;));
if (diffDays &lt; nearestDayDiff || (diffDays === nearestDayDiff &amp;&amp; slotDateTime.isBefore(nearestSlot))) {
nearestDayDiff = diffDays;
nearestSlot = slotDateTime;
}
}
}
}
return nearestSlot ? nearestSlot.format(&#39;ddd, h:mm a&#39;) : &quot;wait for next week&quot;;
}
function findNearestFreeSlotMyTry(slotsArray) {
const currentDate = moment().day(fakeDay);
const indexDays = { sun: 0, mon: 1, tue: 2, wed: 3, thu: 4, fri: 5, sat: 6 };
const listSlots = slotsArray
.reduce((prev, { day, freeSlots }) =&gt; { // Converto the object of free slots in to array with the difference
for (const slot of freeSlots) {
const dateSlot = moment(slot, &#39;h:mm a&#39;).day(indexDays[day]);
const diff = dateSlot.diff(currentDate);
if (diff &gt;= 0) prev.push({ diff, date: dateSlot.format(&#39;ddd, h:mm a&#39;) }); // Get elements only if is in the fucture
}
return prev;
}, [])
.sort((a, b) =&gt; a.diff &lt; b.diff ? -1 : 1); //  sort the array by diff, from the nearlest to further
return listSlots?.[0]?.date || &#39;wait for next week&#39;; // Return the date or the string
}
const freeSlotsArray = [
{
day: &#39;wed&#39;,
freeSlots: [/* &#39;12:00 am&#39;, */ &#39;12:00 pm&#39;, &#39;1:00 pm&#39;, &#39;1:30 pm&#39;, &#39;2:30 pm&#39;, &#39;3:00 pm&#39;, &#39;3:30 pm&#39;, &#39;4:30 pm&#39;, &#39;5:00 pm&#39;, &#39;6:30 pm&#39;, &#39;7:00 pm&#39;]
},
{
day: &#39;sat&#39;,
freeSlots: [&#39;7:00 am&#39;, &#39;7:30 am&#39;, &#39;8:00 am&#39;, &#39;9:00 am&#39;, &#39;10:00 am&#39;, &#39;10:30 am&#39;, &#39;11:30 am&#39;, &#39;12:00 pm&#39;, &#39;12:30 pm&#39;]
},
{
day: &#39;thu&#39;,
freeSlots: [&#39;12:00 pm&#39;, &#39;1:00 pm&#39;, &#39;1:30 pm&#39;, &#39;2:30 pm&#39;, &#39;4:00 pm&#39;, &#39;5:30 pm&#39;, &#39;6:30 pm&#39;, &#39;7:00 pm&#39;]
},
{
day: &#39;mon&#39;,
freeSlots: [&#39;4:00 pm&#39;, &#39;4:30 pm&#39;, &#39;6:00 pm&#39;, &#39;6:30 pm&#39;, &#39;7:30 pm&#39;, &#39;8:00 pm&#39;, &#39;8:30 pm&#39;, &#39;9:30 pm&#39;]
}
];
const nearestFreeSlot = findNearestFreeSlot(freeSlotsArray);
console.log(&#39;-----&gt; &#39;, nearestFreeSlot);
const nearestFreeSlotMyTry = findNearestFreeSlotMyTry(freeSlotsArray);
console.log(&#39;-----&gt; &#39;, nearestFreeSlotMyTry);

<!-- language: lang-html -->

&lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/moment.min.js&quot;&gt;&lt;/script&gt;

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年7月27日 18:05:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/76778642.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定