Разделение диапазона дат перекрывается на фрагменты (javascript)

Я придумал концепцию, но у меня проблемы с преобразованием ее в код.

Вот картинка, которая лучше поясняет мою идею: Разделение диапазона дат перекрывается на фрагменты (javascript)

По картинке не видно, но между датами тоже могут быть пробелы.

Чтобы не превращать это в XY-проблему, вот почему мне это нужно. У меня есть массив диапазонов дат и бонусов, и я хочу создать массив неперекрывающихся дат с суммой бонусов.

Я пытаюсь разделить перекрытия на патроны, которые больше не перекрываются. Наткнулся на пакет под названием момент-диапазон. Может быть, есть название для того, что я пытаюсь добиться? "Проецирование диапазонов дат на линейные ... что-то"

Окончательный код ниже

const _ = require('lodash')
const Moment = require('moment')
const MomentRange = require('moment-range')

const moment = MomentRange.extendMoment(Moment);

let bonuses = [
  {start: new Date('Jan 15, 2018 23:00:00 GMT+0200'), end: new Date('Jan 18, 2018 23:59:59 GMT+0200'), bonus: 30, preSale: true},
  {start: new Date('Jan 17, 2018 00:00:00 GMT+0200'), end: new Date('Jan 29, 2018 13:00:00 GMT+0200'), bonus: 25, preSale: true},
  {start: new Date('Feb 12, 2018 00:00:00 GMT+0200'), end: new Date('Feb 18, 2018 23:59:59 GMT+0200'), bonus: 20, preSale: false},
  {start: new Date('Feb 19, 2018 00:00:00 GMT+0200'), end: new Date('Feb 27, 2018 23:59:59 GMT+0200'), bonus: 15, preSale: false},
  {start: new Date('Feb 26, 2018 00:00:00 GMT+0200'), end: new Date('Mar 4, 2018 23:59:59 GMT+0200'), bonus: 10, preSale: false},
  {start: new Date('Mar 5, 2018 00:00:00 GMT+0200'), end: new Date('Mar 11, 2018 23:59:59 GMT+0200'), bonus: 5, preSale: false},
]

_.map(bonuses, o => o.range = moment.range(o.start, o.end))

let dates = []
_.each(bonuses, o => {
  dates.push(o.start)
  dates.push(o.end)
})

dates.sort(function(a, b) {
  return a-b
})

let ranges = []
for(let i=1; i<dates.length; i++) {
  ranges.push({
    start: dates[i-1],
    end: dates[i],
    range: moment.range(dates[i-1], dates[i])
  })
}

for (let range of ranges) {
  range.bonus = 0
  for (let bonus of bonuses) {
    if (range.range.intersect(bonus.range)) {
      range.bonus += bonus.bonus
    }
  }
}

_.each(ranges, r => console.info(r.start, ' - ', r.end, '  => ', r.bonus))

Судя по картинке, я бы сказал, что вы просто помещаете все свои начальные и конечные времена в массив, сортируете их ... и там у вас есть «границы» для всех ваших целевых интервалов ...?

CBroe 30.05.2018 13:17

@CBroe Я обновил вопрос, что вы предлагаете мне делать сейчас?

keeeenion 30.05.2018 15:47
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
2
1 298
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Что-то вроде этого?

var min = Infinity;
var max = 0;
var bonuses = [
    { start: new Date('Jan 15, 2018 23:00:00 GMT+0200'), end: new Date('Jan 18, 2018 23:59:59 GMT+0200'), bonus: 30, intersects: false },
    { start: new Date('Jan 16, 2018 00:00:00 GMT+0200'), end: new Date('Jan 29, 2018 13:00:00 GMT+0200'), bonus: 25, intersects: false },
    { start: new Date('Feb 12, 2018 00:00:00 GMT+0200'), end: new Date('Feb 18, 2018 23:59:59 GMT+0200'), bonus: 20, intersects: false },
    { start: new Date('Feb 19, 2018 00:00:00 GMT+0200'), end: new Date('Feb 29, 2018 23:59:59 GMT+0200'), bonus: 15, intersects: false },
    { start: new Date('Feb 26, 2018 00:00:00 GMT+0200'), end: new Date('Mar 4, 2018 23:59:59 GMT+0200'), bonus: 10, intersects: false },
    { start: new Date('Mar 5, 2018 00:00:00 GMT+0200'), end: new Date('Mar 11, 2018 23:59:59 GMT+0200'), bonus: 5, intersects: false }
];
bonuses
    .map(function (a, index) {
    if (a.start.getTime() < min) {
        min = a.start.getTime();
    }
    if (a.end.getTime() < min) {
        min = a.end.getTime();
    }
    if (a.start.getTime() > max) {
        max = a.start.getTime();
    }
    if (a.end.getTime() > max) {
        max = a.end.getTime();
    }
    for (var i = index + 1; i < bonuses.length; i++) {
        var b = bonuses[i];
        if (b.start.getTime() < a.start.getTime() && b.end.getTime() > a.start.getTime() ||
            a.start.getTime() < b.start.getTime() && a.end.getTime() > b.start.getTime()) {
            bonuses[i].intersects = true;
            a.intersects = true;
        }
    }
    return a;
});
var tileSize = 20;
var canvas = document.body.appendChild(document.createElement("canvas"));
canvas.width = 800;
canvas.height = bonuses.length * tileSize;
var ctx = canvas.getContext("2d");
bonuses.forEach(function (bonus, index) {
    var start = (bonus.start.getTime() - min) / (max - min);
    var end = (bonus.end.getTime() - min) / (max - min);
    ctx.fillStyle = bonus.intersects ? "red" : "green";
    ctx.fillRect(canvas.width * start, tileSize * index, canvas.width * (end - start), tileSize);
    ctx.strokeRect(canvas.width * start, tileSize * index, canvas.width * (end - start), tileSize);
});

Это, безусловно, помогает с визуализацией, но не помогает мне решить проблему.

keeeenion 30.05.2018 15:51
Ответ принят как подходящий
var dates = [];
bonuses.forEach(item => {
    dates.push(item.start);
    dates.push(item.end);
});
dates.sort();
var ranges = [];
for(var i=1;i<dates.length;i++){
    ranges.push({
        start: dates[i-1], 
        end: dates[i]
    });
}
console.info(ranges);

Извините, что не заметил, это именно то, что мне нужно. Спасибо :)

keeeenion 02.06.2018 03:14

Другие вопросы по теме