Как смержить расписания?
Я не могу понять, как реализовать сливание расписаний. Есть два расписания:
var accessSchedules = new[]{
new AccessScheduleCycle[]{
new( new LocalDateInterval( new LocalDate( 2022, 1, 1 ) ),
new AccessScheduleCycleDay[] { // days }
}
new AccessScheduleCycle[]{
new( new LocalDateInterval( new LocalDate( 2022, 1, 7 ) ),
new AccessScheduleCycleDay[] { // days }
),
new( new LocalDateInterval( new LocalDate( 2022, 1, 21 ) ),
new AccessScheduleCycleDay[] { // days }
),
new( new LocalDateInterval( new LocalDate( 2022, 3, 18 ) ),
new AccessScheduleCycleDay[] { // days }
)
}
}
Как можно видеть, у второго расписания есть несколько интервалов, т.е с 7 числа, рабочие дни будут одни, с 21 числа, другие. Слиться должны дни, а вот результат будущего слияния:
{
"cycles": [{
"days": [[], ["/"], ["/"], ["/"], [], [], []],
"interval": "2022-01-01/"
}, { //Результат сложения
"days": [["/"], [], ["/"], ["/"], ["/"], [], []],
"interval": "2022-01-07/"
}, { //Результат сложения
"days": [["/"], [], ["/"], [], ["/"], [], []],
"interval": "2022-01-21/"
}, { //Результат сложения
"days": [["/"], [], ["08:00/11:00"], [], ["/"], ["/"], []],
"interval": "2022-03-18/"
}
]
}
Я написал следующий код, который работает только если во 2ом расписании будет одна дата ( допустим, оно начнет действовать с 7 числа ). Как действовать, если дат много, я не знаю. Результатом кода, который ниже, будет массив, состоящий из дней и одной максимальной даты. Прилагаю картинку того, как должно работать на самом деле.
// length of array is lcm of access schedules elements
var daysCount = accessSchedules
.SelectMany( x => x )
.Select( x => x.Days.Count )
.Aggregate( MathExtension.LeastCommonMultiple );
// create empty arrays in the amount of LCM
var result = Enumerable
.Repeat(0, daysCount)
.Select(_ => new List<LocalTimeInterval>())
.ToArray();
// add time intervals to arrays
foreach (var schedule in accessSchedules
.SelectMany( x => x).Select( x => x.Days ))
{
var index = 0;
for (var i = 0; i < daysCount; i++)
{
foreach (var localTimeInterval in schedule[ index ].Intervals) result[ i ].Add( localTimeInterval );
index = (index + 1) % schedule.Count;
}
}
// sort and merge intervals in array
var maxInterval = accessSchedules
.SelectMany( x => x)
.Select( x => x.Interval )
.Max();
var accessSchedule = new AccessScheduleCycle
{
Interval = maxInterval
};
for ( var i = 0; i < daysCount; i++ )
{
var intervals = result[ i ];
var mergedIntervals = Merge( intervals );
accessSchedule.Days.AddRange( new List<AccessScheduleCycleDay>() { new ( mergedIntervals ) });
}
return accessSchedule;

