创建一个日期数组的有效方法?

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

Creating an array of dates efficiently?

问题

以下是您要的内容的翻译:

我有一个名为availabilities的集合。在这个集合中,可能会有一些基于日期的条目,例如:

{
  "_id": "64b03ed794d87927a3066e13",
  "startDateTime": "2023-07-07T18:00:00.000Z",
  "endDateTime": "2023-07-12T15:00:00.000Z",
  "availabilityType": "blackout"
}
{
  "_id": "64b03eb094d87927a3066ddb",
  "startDateTime": "2023-07-03T18:00:00.000Z",
  "endDateTime": "2023-07-06T15:00:00.000Z",
  "availabilityType": "blackout"
}

我正在尝试找出创建一个日期数组的最佳方法,如果某些日期有“可用性”,则在日期数组中返回该日期。我考虑使用JavaScript创建一个日期数组,然后对每一天进行迭代以查看是否有任何日期上的availabilities,但这似乎非常低效。

理想情况下,我希望构建类似以下的内容:

[
  {
    "date": "2023-07-01",
    "availabilityType": "available"
  },
  {
    "date": "2023-07-02",
    "availabilityType": "available"
  },
  {
    "date": "2023-07-03",
    "availabilityType": "booked" //因为在集合中有一个标记为booked的可用性条目
  },
  {
    "date": "2023-07-04",
    "availabilityType": "booked" //因为在集合中有一个标记为booked的可用性条目
  },
  {
    "date": "2023-07-05",
    "availabilityType": "booked" //因为在集合中有一个标记为booked的可用性条目
  },
  {
    "date": "2023-07-06",
    "availabilityType": "booked" //因为在集合中有一个标记为booked的可用性条目
  },
  ...等等,一直到7月31日
]

对于如何实现这个目标,您有什么建议?

英文:

I have an availabilities collection. Inside this collection could be a few entries that are date based for example:

{
  "_id": "64b03ed794d87927a3066e13",
  "startDateTime": "2023-07-07T18:00:00.000Z",
  "endDateTime": "2023-07-12T15:00:00.000Z",
  "availabilityType": "blackout"
}
{
  "_id": "64b03eb094d87927a3066ddb",
  "startDateTime": "2023-07-03T18:00:00.000Z",
  "endDateTime": "2023-07-06T15:00:00.000Z",
  "availabilityType": "blackout"
}

I am trying to figure out the best way to create an array of dates for the month and if there is an “availability” for some of the days, then return that within the date array. I thought about creating an array of days using javascript but then I’d have to iterate for each day to see there are any availabilities on the day; this seems very inefficient.

Ideally what I am looking to build is something similar to the following:

[
  {
    "date": "2023-07-01",
    "availabilityType": "available"
  },
  {
    "date": "2023-07-02",
    "availabilityType": "available"
  },
  {
    "date": "2023-07-03",
    "availabilityType": "booked" // because there was an availability entry in the collection that is marked as booked
  },
  {
    "date": "2023-07-04",
    "availabilityType": "booked" // because there was an availability entry in the collection that is marked as booked
  },
  {
    "date": "2023-07-05",
    "availabilityType": "booked" // because there was an availability entry in the collection that is marked as booked
  },
  {
    "date": "2023-07-06",
    "availabilityType": "booked" // because there was an availability entry in the collection that is marked as booked
  },
  ... etc up to July 31
]

Any suggestions on how this might be done?

答案1

得分: 1

以下是翻译好的部分:

这是另一种方法

const bookings = [
  { "_id": "64b03ed794d87927a3066e13", "startDateTime": "2023-07-07T18:00:00.000Z", "endDateTime": "2023-07-12T15:00:00.000Z", "availabilityType": "blackout" },
  { "_id": "64b03eb094d87927a3066ddb", "startDateTime": "2023-07-03T18:00:00.000Z", "endDateTime": "2023-07-06T15:00:00.000Z", "availabilityType": "blackout" }
];

const monthCal = {}; // 设置一个月的日历:2023年7月
for (let d = 1, m = 6, y = 2023, ld = new Date(y, m + 1, 0).getDate(); // 设置为第二天的00:00
     d <= ld; d++) monthCal[`${y}-${String(m + 1).padStart(2, "0")}-${String(d).padStart(2, "0")}`] = false;

bookings.forEach(b => {
  // 将截止日期ld定义为“00:00h”,即endDateTime的后一天:
  const ld = new Date(b.endDateTime);
  ld.setDate(ld.getDate() + 1);
  ld.setHours(0);
  for (let d = new Date(b.startDateTime); d < ld; d.setDate(d.getDate() + 1))
    monthCal[d.toISOString().slice(0, 10)] = true;
});

console.log(monthCal)

// 或者如果你想要原始的输出格式:

console.log(Object.entries(monthCal).map(([date, v]) => ({ date, availabilityType: v ? "booked" : "available" })));

由于monthCal对象允许直接查找日期,而无需使用内部循环,这可能比扫描对象数组稍微更高效。

英文:

Here is another take on it:

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

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

const bookings=[{ &quot;_id&quot;: &quot;64b03ed794d87927a3066e13&quot;, &quot;startDateTime&quot;: &quot;2023-07-07T18:00:00.000Z&quot;,
  &quot;endDateTime&quot;: &quot;2023-07-12T15:00:00.000Z&quot;, &quot;availabilityType&quot;: &quot;blackout&quot;},
 {&quot;_id&quot;: &quot;64b03eb094d87927a3066ddb&quot;, &quot;startDateTime&quot;: &quot;2023-07-03T18:00:00.000Z&quot;,
  &quot;endDateTime&quot;: &quot;2023-07-06T15:00:00.000Z&quot;, &quot;availabilityType&quot;: &quot;blackout&quot; }];

 const monthCal={}; // set up the calendar for one month: July 2023   
 for (let d=1, m=6, y=2023, ld=new Date(y,m+1,0).getDate(); // set to 00:00h the following day
      d &lt;= ld; d++ ) monthCal[`${y}-${String(m+1).padStart(2,&quot;0&quot;)}-${String(d).padStart(2,&quot;0&quot;)}`]=false;
      
bookings.forEach(b=&gt;{
 // define the cut-off date ld as &quot;00:00h&quot;, the day after endDateTime:
 const ld=new Date(b.endDateTime); ld.setDate(ld.getDate()+1); ld.setHours(0);
 for (let d=new Date(b.startDateTime); d &lt; ld; d.setDate(d.getDate()+1)) 
  monthCal[d.toISOString().slice(0,10)]=true;
});

console.log(monthCal)

// or if you want the original output format:

console.log(Object.entries(monthCal).map(([date,v])=&gt;({date,availabilityType:v?&quot;booked&quot;:&quot;available&quot;})));

<!-- end snippet -->

As the monthCal object allows the dates to be found directly, without using in inner loop, this might be slightly more efficient then scanning through an array of objects.

答案2

得分: 1

你可以通过定义startDateendDate来简单实现这个目标,以表示你想要获取详细信息的月份范围。为了演示目的,我正在使用七月的月份范围。

const startDate = new Date("2023-07-01");
const endDate = new Date("2023-07-31");

然后,我们将使用for循环遍历每个日期,从startDate开始,每天递增,直到endDate

在循环内部,我们检查当前日期是否在数组中任何具有availabilityType为“blackout”的对象的startDateTimeendDateTime范围内。如果是,isBooked变量将设置为true,表示该日期已预订。否则,isBooked保持为false,表示该日期可用。

最后,对于每个日期,我们将一个对象推送到allDates数组中,将日期属性设置为格式化的日期字符串,将可用属性根据isBooked值设置为“booked”或“available”。

希望这对你有帮助!

英文:

You can simply achieve this by defining a startDate and an endDate to represent the range of dates for the month you want to get the details. For demo purpose, I am using July month range.

const startDate = new Date(&quot;2023-07-01&quot;);
const endDate = new Date(&quot;2023-07-31&quot;);

Then, we will iterate over each date using a for loop, starting from the startDate and incrementing by one day until the endDate.

Within the loop, we check if the current date falls within the startDateTime and endDateTime range of any object in the array with the availabilityType blackout. If it does, the isBooked variable is set to true, indicating that the date is booked. Otherwise, isBooked remains false, indicating that the date is available.

Finally, we push an object to the allDates array for each date, setting the date property to the formatted date string and the available property to either booked or available based on the isBooked value.

Live Demo :

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

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

const array = [
  {
    &quot;_id&quot;: &quot;64b03ed794d87927a3066e13&quot;,
    &quot;startDateTime&quot;: &quot;2023-07-07T18:00:00.000Z&quot;,
    &quot;endDateTime&quot;: &quot;2023-07-12T15:00:00.000Z&quot;,
    &quot;availabilityType&quot;: &quot;blackout&quot;
  },
  {
    &quot;_id&quot;: &quot;64b03eb094d87927a3066ddb&quot;,
    &quot;startDateTime&quot;: &quot;2023-07-03T18:00:00.000Z&quot;,
    &quot;endDateTime&quot;: &quot;2023-07-06T15:00:00.000Z&quot;,
    &quot;availabilityType&quot;: &quot;blackout&quot;
  }
];

const startDate = new Date(&quot;2023-07-01&quot;);
const endDate = new Date(&quot;2023-07-31&quot;);

const allDates = [];
for (let date = startDate; date &lt;= endDate; date.setDate(date.getDate() + 1)) {
  const dateString = date.toISOString().split(&#39;T&#39;)[0];
  const isBooked = array.some(item =&gt; {
    const startDateTime = new Date(item.startDateTime);
    const endDateTime = new Date(item.endDateTime);
    return dateString &gt;= startDateTime.toISOString().split(&#39;T&#39;)[0] &amp;&amp; dateString &lt;= endDateTime.toISOString().split(&#39;T&#39;)[0] &amp;&amp; item.availabilityType === &quot;blackout&quot;;
  });
  allDates.push({ date: dateString, available: isBooked ? &quot;booked&quot; : &quot;available&quot; });
}

console.log(allDates);

<!-- end snippet -->

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

发表评论

匿名网友

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

确定