Как смержить расписания?

Я не могу понять, как реализовать сливание расписаний. Есть два расписания:

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;          

введите сюда описание изображения введите сюда описание изображения


Ответы (0 шт):