С Новым годом! Форум программистов, компьютерный форум, киберфорум
JavaScript
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
191 / 55 / 18
Регистрация: 22.08.2021
Сообщений: 99

Получение пересечения из массива дат и их модификация

16.08.2025, 08:35. Показов 1092. Ответов 7
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет.
На мой взгляд банальная задача, но я что-то с ней застрял.
Просидел пару часов и получился индусский код, как по моему.
Дан массив с объектами {from: string, to?: string}.
Нужно получить из него массив дат без пересечения друг с другом. По сути это опыт работы, нужно вычислить общий стаж. Если нет свойства to, тогда считается что по настоящее время.
В проекте date-fns, но там никаких методов для этого не нашел (кроме простого чека пересечения даты).

Есть у кого желание/возможности глянуть?

Мой вариант

TypeScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
type DateObject = {
    from?: string | Date;
    to?: string | Date;
};
 
const checkIntersectionDates = (
    dates: DateObject[],
) => {
    let datesForInterval: Required<DateObject>[] = [];
    dates.map((date) => {
        if (!date.from) {
            return;
        }
        const newDate = {
            from: new Date(date.from),
            to: date.to ? new Date(date.to) : new Date(),
        };
        if (datesForInterval.length === 0) {
            datesForInterval.push(newDate);
            return;
        }
 
        let isNeedToPush = false;
 
        datesForInterval = datesForInterval.map((intervalDate) => {
            const isFromBetween =
                newDate.from >= intervalDate.from &&
                newDate.from <= intervalDate.to;
            const isToBetween =
                newDate.to >= intervalDate.from &&
                newDate.to <= intervalDate.to;
            const isFromLessAndToMore =
                newDate.from < intervalDate.from &&
                newDate.to > intervalDate.to;
            if (isFromBetween || isToBetween || isFromLessAndToMore) {
                if (isFromBetween && isToBetween) {
                    return intervalDate;
                } else if (isFromLessAndToMore) {
                    return newDate;
                } else if (isFromBetween) {
                    return {
                        from: intervalDate.from,
                        to: newDate.to,
                    };
                } else if (isToBetween) {
                    return {
                        from: newDate.from,
                        to: intervalDate.to,
                    };
                }
            }
            isNeedToPush = true;
            return intervalDate;
        });
 
        if (
            isNeedToPush &&
            !datesForInterval.some((intervalDate) => {
                const isFromBetween =
                    newDate.from >= intervalDate.from &&
                    newDate.from <= intervalDate.to;
                const isToBetween =
                    newDate.to >= intervalDate.from &&
                    newDate.to <= intervalDate.to;
                const isFromLessAndToMore =
                    newDate.from < intervalDate.from &&
                    newDate.to > intervalDate.to;
                return isFromBetween || isToBetween || isFromLessAndToMore;
            })
        ) {
            datesForInterval.push(newDate);
        }
    });
 
    console.log(datesForInterval);
    return datesForInterval;
 
};
 
checkIntersectionDates([
    { from: '2016-01-01', to: '2018-01-01' },
    { from: '2017-01-01', to: '2019-01-01' },
    { from: '2021-01-01', to: '2024-01-01' },
    { from: '2023-01-01' },
]);
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
16.08.2025, 08:35
Ответы с готовыми решениями:

Модификация всех элементов массива
в общем есть запрос SELECT I.Id, I.price,I.name, S.sales, S.price FROM dbo.items I, dbo.Sales S...

Модификация счетчика
Добрый день. Помогите модифицировать скрипт счетчика обратного отсчета:...

Модификация уже известного скрипта - вывод текста при клике
Возможно кто-то подскажет решение или направит куда смотреть и что можно менять Есть скрипт, он...

7
 Аватар для voraa
1244 / 1145 / 178
Регистрация: 21.01.2024
Сообщений: 5,270
16.08.2025, 12:55
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
const compDate = (d1, d2) => new Date(d1) - new Date(d2);
 
const checkIntersectionDates = (dates) => {
    const result = [];
    for (let {from, to} of dates) {
        let needPush = true;
        to ??= new Date().toISOString().slice(0,10);
        for (const res of result) {
            const {from:resfrom, to:resto} = res;
            if (compDate(resto, from) >= 0 && compDate (resfrom, to) <= 0) {
                if (compDate(to, resto) > 0) res.to = to;
                if (compDate(from, resfrom) < 0) res.from = from;
                needPush = false;
                break;
            }
        }
        if (needPush) result.push({from, to});
    }
    return result;
}
 
const res = checkIntersectionDates([
    { from: '2016-01-01', to: '2018-01-01' },
    { from: '2017-01-01', to: '2019-01-01' },
    { from: '2021-01-01', to: '2024-01-01' },
    { from: '2023-01-01' },
]);
 
console.log(res); // => [{from: '2016-01-01', to: '2019-01-01'}, {from: '2021-01-01', to: '2025-08-16'}]
Добавлено через 9 минут
PS. Массив надо отсортировать по from.
1
Эксперт JSЭксперт HTML/CSS
 Аватар для krvsa
3818 / 1656 / 428
Регистрация: 14.03.2022
Сообщений: 4,132
17.08.2025, 17:56
Цитата Сообщение от Jsuser Посмотреть сообщение
нужно вычислить общий стаж
Когда-то использовал такую идею...

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
const a = test([
    { from: '2016-01-01', to: '2018-01-01' },
    { from: '2017-01-01', to: '2019-01-01' },
    { from: '2021-01-01', to: '2024-01-01' },
    { from: '2023-01-01' },
]);
console.log(a)
//
function test(arr){
    return arr.reduce((a, {from, to = (new Date).toISOString().split('T')[0]}) => (
        a.push([from, 1], [to, 0]), a
    ), [])
        .toSorted(([a], [b]) => a === b? 0: a > b? 1: -1)
        .reduce((o, [d, t]) => {
            if (t !== o.t) {
                o.a.push(d)
                o.t = t
                if (!t) {
                    o.res.push(o.a)
                    o.a = []
                }
            } 
            return o
        }, {res: [], a: [], t: 0}).res
}
Добавлено через 1 минуту
P.S. массив на входе сортировать не обязательно...
0
 Аватар для voraa
1244 / 1145 / 178
Регистрация: 21.01.2024
Сообщений: 5,270
17.08.2025, 18:59
Цитата Сообщение от krvsa Посмотреть сообщение
Когда-то использовал такую идею...
А результат проверял?
Получается
Code
1
2
3
(2) [Array(2), Array(2)]
0: (2) ['2016-01-01', '2018-01-01']
1: (2) ['2021-01-01', '2024-01-01']
А должно быть
[{from: '2016-01-01', to: '2019-01-01'}, {from: '2021-01-01', to: '2025-08-17'}]

Добавлено через 10 минут
В моем варианте сортировать надо (можно и внутри функции)
Иначе
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
const compDate = (d1, d2) => new Date(d1) - new Date(d2);
 
const checkIntersectionDates = (dates) => {
    const result = [];
    for (let {from, to} of dates) {
        let needPush = true;
        to ??= new Date().toISOString().slice(0,10);
        for (const res of result) {
            const {from:resfrom, to:resto} = res;
            if (compDate(resto, from) >= 0 && compDate (resfrom, to) <= 0) {
                if (compDate(to, resto) > 0) res.to = to;
                if (compDate(from, resfrom) < 0) res.from = from;
                needPush = false;
                break;
            }
        }
        if (needPush) result.push({from, to});
    }
    return result;
}
 
const res = checkIntersectionDates([
    { from: '2017-01-01', to: '2019-01-01' },
    { from: '2021-01-01', to: '2023-01-01' },
    { from: '2018-01-01', to: '2022-01-01' },
]);
console.log(res);
Дает неверный результат
Code
1
2
0: {from: '2017-01-01', to: '2022-01-01'}
1: {from: '2021-01-01', to: '2023-01-01'}
А так
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
const compDate = (d1, d2) => new Date(d1) - new Date(d2);
 
const checkIntersectionDates = (dates) => {
    const result = [];
    dates = dates.toSorted((a,b) => a.from < b.from? -1 : a.from > b.from? 1 : 0);
    for (let {from, to} of dates) {
        let needPush = true;
        to ??= new Date().toISOString().slice(0,10);
        for (const res of result) {
            const {from:resfrom, to:resto} = res;
            if (compDate(resto, from) >= 0 && compDate (resfrom, to) <= 0) {
                if (compDate(to, resto) > 0) res.to = to;
                if (compDate(from, resfrom) < 0) res.from = from;
                needPush = false;
                break;
            }
        }
        if (needPush) result.push({from, to});
    }
    return result;
}
 
const res = checkIntersectionDates([
    { from: '2017-01-01', to: '2019-01-01' },
    { from: '2021-01-01', to: '2023-01-01' },
    { from: '2018-01-01', to: '2022-01-01' },
]);
 
console.log(res);
Правильно

Code
1
0: {from: '2017-01-01', to: '2023-01-01'}
0
Эксперт JSЭксперт HTML/CSS
 Аватар для krvsa
3818 / 1656 / 428
Регистрация: 14.03.2022
Сообщений: 4,132
17.08.2025, 19:42
Цитата Сообщение от voraa Посмотреть сообщение
А должно быть
У всех "надобности" разные...
Если нужен именно такой результат - значит мой вариант не подойдет.

Добавлено через 15 минут
Цитата Сообщение от voraa Посмотреть сообщение
А должно быть
JavaScript
1
[{from: '2016-01-01', to: '2019-01-01'}, {from: '2021-01-01', to: '2025-08-17'}]
Такой вариант будет такое возвращать...

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const a = test([
    { from: '2016-01-01', to: '2018-01-01' },
    { from: '2017-01-01', to: '2019-01-01' },
    { from: '2021-01-01', to: '2024-01-01' },
    { from: '2023-01-01' },
]);
console.log(a)
//
function test(arr){
    return arr.reduce((a, {from, to = (new Date).toISOString().split('T')[0]}) => (
        a.push([from, 1], [to, 0]), a
    ), [])
        .toSorted(([a], [b]) => a === b? 0: a > b? 1: -1)
        .reduce((o, [d, t]) => {
            if (!t || (t && !o.a[t])) o.a[t] = d
            o.t += t? 1: -1 
            if (!o.t) {
                o.res.push(o.a.reverse())
                o.t = 0
                o.a = []
            }
            return o
        }, {res: [], a: [], t: 0}).res
}
0
 Аватар для voraa
1244 / 1145 / 178
Регистрация: 21.01.2024
Сообщений: 5,270
17.08.2025, 19:43
Цитата Сообщение от krvsa Посмотреть сообщение
У всех "надобности" разные...
А какую задачу решает твой вариант?
У ТС сказано, что это типа стажа
Если есть
Code
1
2
    { from: '2016-01-01', to: '2018-01-01' },
    { from: '2017-01-01', to: '2019-01-01' },
То можно сказать, что чел работал с
Code
1
{ from: '2016-01-01',  to: '2019-01-01' }
1
Эксперт JSЭксперт HTML/CSS
 Аватар для krvsa
3818 / 1656 / 428
Регистрация: 14.03.2022
Сообщений: 4,132
17.08.2025, 19:49
Цитата Сообщение от voraa Посмотреть сообщение
А какую задачу решает твой вариант?
У ТС сказано, что это типа стажа
Это пособие так считали. Если его прекратили - значит все.
Там т.о. собирали интервалы дат и потом по количеству дней делали начисление...

Добавлено через 1 минуту
Цитата Сообщение от voraa Посмотреть сообщение
У ТС сказано, что это типа стажа
Я просто вспомнил что там так же были периоды с датами - вот и написал как там реализовывали.
А со стажем ты все правильно написал.
0
191 / 55 / 18
Регистрация: 22.08.2021
Сообщений: 99
09.09.2025, 12:43  [ТС]
Всем спасибо, взял на заметку
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
09.09.2025, 12:43
Помогаю со студенческими работами здесь

Модификация Моно фильтра в мульти фильтр
Здравствуйте, есть шаблон моно фильтра. То бишь, фильтр сортирует лишь по 1 критерию. Нужно...

Хранение и модификация данных
Настраиваю хотспот на роутере, на страничке логина имею 3 кнопки. Нужно только силами html и...

Автоматическая модификация страниц браузером
Здравствуйте, есть такая задача: нужна автоматическая модификация страниц через скрипт в браузере,...

Модификация скрипта Java Script
Скажите пожалуйста, каким образом можно модифицировать данный скрипт, чтобы он отображал степени...

Чтение и модификация больших JSON файлов
Есть файлы JSON, в которым мне нужно найти определенные поля , модифицировать их и сохранить...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
Изучаю kubernetes
lagorue 13.01.2026
А пригодятся-ли мне знания kubernetes в России?
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru