Node.js:如何计算两个日期数组的交集?

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

Nodejs: how to make intersection of two arrays of dates

问题

如何正确执行矩阵的交集。我正在使用Node.js进行开发,尝试比较两个数组以获取相同的元素,即“数组交集”。

这实际上是一个相当常见的问题,尽管我已经搜索并应用了您提到的解决方法,但仍然不明白为什么它不起作用。我有两个日期数组,日期的格式相同,所以我排除了它不起作用的可能性。

我使用了最常见的解决方法,即使用filter()方法来过滤数组,并通过include()方法验证数组B是否包含数组A的任何元素。

然后尝试使用some()方法来检查数组,直到它返回true值为止。

在我的情况下,我正在通过日期范围生成一个新数组,其中包含从范围的开始到结束的日期。

以下代码返回一个名为“someDates”的数组,该数组是尝试将“currentWeek”数组与“holidaysDates”数组进行交集的结果。

但我不明白为什么它不起作用?

function getArrayOfRangeDate(startDate, endDate) {
    let dates = [];
    let currentDate = startDate;

    while (currentDate <= endDate) {
        dates.push(new Date(currentDate));
        currentDate.setDate(currentDate.getDate() + 1);
    }

    return dates;
}

users.map(user => {

    let user_id = user.id;
    let username = user.username;
    let modality = user.modality.name;

    isHoliday.forEach((schedule: AttendanceSchedule) => {

        let startDate1 = new Date(datestart);
        let endDate1 = new Date(dateend);
        let startDate2 = new Date(schedule.date_start);
        let endDate2 = new Date(schedule.date_end);

        const currentWeek = getArrayOfRangeDate(startDate1, endDate1);
        const holidaysDates = getArrayOfRangeDate(startDate2, endDate2);

        const results = currentWeek.filter(o1 => holidaysDates.some(o2 => o1 === o2));
        // console.log('sameDates', results);

        newListOfSchedule.push({
            user_id: user_id,
            username: username,
            modality: modality,
            currentWeek: currentWeek,
            holidaysDates: holidaysDates,
            sameDates: results
        });

    });
});

简单的演示:

const arrayA = [
    "2022-12-19T00:00:00.000Z",
    "2022-12-20T00:00:00.000Z",
    "2022-12-21T00:00:00.000Z",
    "2022-12-22T00:00:00.000Z",
    "2022-12-23T00:00:00.000Z",
    "2022-12-24T00:00:00.000Z",
    "2022-12-25T00:00:00.000Z"
]

const arrayB = [
    "2022-12-19T00:00:00.000Z",
    "2022-12-20T00:00:00.000Z"
]

const results = arrayA.filter(o1 => arrayB.some(o2 => o1 === o2));

console.log('results', results)

总之,我想遍历数组A并将其与数组B进行比较,以返回两个数组中相同的元素。我还提供了一些链接,这些链接解释了我认为值得分享的数组交集的方法:

英文:

How to do an intersection of matrices correctly. I'm working in nodejs and I'm trying to compare two arrays to get the same elements i.e. an "array intersection"

This is a pretty common question, actually, and even though I've searched and applied the resolutions you mention, I still don't understand why I can't. I have two arrays of dates, and the dates I'm handling are in the same format, so I'm ruling out the possibility that it won't work for that reason.

I used the most common solution, which was to use the filter() method to filter the array and validate via the include() method if array B includes any of the elements of array A.

Then try the same thing but with the some() method to check the array until it returns a true value.

In my case, what I am doing is through a range of dates, I generate a new array with the dates from the start to the end of the range.

The following code returns an array in "someDates" which is the result of trying to intercept the "currentWeek" array with the "holidaysDates" array

But I don't understand why it doesn't work?

function getArrayOfRangeDate(startDate, endDate) {

    let dates: any[] = [];
    let currentDate = startDate;

    while (currentDate &lt;= endDate) {
        dates.push(new Date(currentDate));
        currentDate.setDate(currentDate.getDate() + 1);
    }

    return dates;
}

            users.map(user =&gt; {

                let user_id = user.id;
                let username = user.username;
                let modality = user.modality.name;

                isHoliday.forEach((schedule: AttendanceSchedule) =&gt; {

                    let startDate1 = new Date(datestart);
                    let endDate1 = new Date(dateend);
                    let startDate2 = new Date(schedule.date_start);
                    let endDate2 = new Date(schedule.date_end);

                    const currentWeek: any[] = getArrayOfRangeDate(startDate1, endDate1);
                    const holidaysDates: any[] = getArrayOfRangeDate(startDate2, endDate2);

                    const results = currentWeek.filter(o1 =&gt; holidaysDates.some(o2 =&gt; o1 === o2));
                    // console.log(&#39;sameDates&#39;, results);

                    newListOfSchedule.push({
                        user_id: user_id,
                        username: username,
                        modality: modality,
                        currentWeek: currentWeek,
                        holidaysDates: holidaysDates,
                        sameDates: results
                    });

                });

DEMO simple

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

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

const arrayA = [
&quot;2022-12-19T00:00:00.000Z&quot;,
&quot;2022-12-20T00:00:00.000Z&quot;,
&quot;2022-12-21T00:00:00.000Z&quot;,
&quot;2022-12-22T00:00:00.000Z&quot;,
&quot;2022-12-23T00:00:00.000Z&quot;,
&quot;2022-12-24T00:00:00.000Z&quot;,
&quot;2022-12-25T00:00:00.000Z&quot;
]

const arrayB = [
&quot;2022-12-19T00:00:00.000Z&quot;,
&quot;2022-12-20T00:00:00.000Z&quot;
]

const results = arrayA.filter(o1 =&gt; arrayB.some(o2 =&gt; o1 === o2));

console.log(&#39;results&#39;, results)

<!-- end snippet -->

In conclusion, what I want to do is go through array A and compare it to array B to return the elements that are the same in both arrays.

I leave you some links where they explain the interception of arrangements that I find interesting to share

答案1

得分: 2

你正在比较两个 Date 对象。在你的示例片段中,你正在比较两个 字符串。使用 === 比较对象时,实际上是通过 引用 进行比较。换句话说,只有两个对象是相同的,当且仅当它们是相同的引用

const a = new Date();
const b = new Date();

a === b // false,不同的对象引用
a === a // true,完全相同的引用

所以当比较日期时,你需要将它们转换为原始值(如字符串或数字):

const results = currentWeek.filter(o1 => holidaysDates.some(o2 => o1.getTime() === o2.getTime()));

我用 getTime 作为示例,它返回表示日期的毫秒数,从纪元开始算起。

英文:

You're comparing two Date objects. In your example snippet, you're comparing two strings. When comparing objects with ===, you're actually comparing by reference. In other words, two objects are the same, only if they are the same reference:

const a = new Date();
const b = new Date();

a === b // false, different object references
a === a // true, exact same reference

So when comparing dates, you need to convert them to a primitive (like a string or number):

const results = currentWeek.filter(o1 =&gt; holidaysDates.some(o2 =&gt; o1.getTime() === o2.getTime()));

I've used getTime as an example which returns a number representing the date as the number of milliseconds since the epoch.

huangapple
  • 本文由 发表于 2023年1月9日 23:22:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/75059398.html
匿名

发表评论

匿名网友

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

确定