2015-12-24 6 views
0

У меня есть класс с именем TimeRange и другой Interval оба же следующую структуруобъединить два списка TimeRanges в один

public class TimeRange 
{ 
    public TimeOfDay start{get; set;} 
    public TimeOfDay end{get; set;} 
} 

У меня есть два списка

List<TimeRange> timeRanges = new List<TimeRange>(); 
timeRanges.Add(new TimeRange(Timespan.FromHours(5), Timespan.FromHours(6))); 
timeRanges.Add(new TimeRange(Timespan.FromHours(8), Timespan.FromHours(9))); 

List<Interval> interval = new List<Interval>(); 
interval.Add(new Interval(Timespan.FromHours(1), Timespan.FromHours(7))); 
interval.Add(new Interval(Timespan.FromHours(10), Timespan.FromHours(15))); 

Я хочу, чтобы объединить эти списки в один так что окончательный результат будет содержать это

Timespan.FromHours(1), Timespan.FromHours(5) 
Timespan.FromHours(5), Timespan.FromHours(6) 
Timespan.FromHours(6), Timespan.FromHours(7) 
Timespan.FromHours(8), Timespan.FromHours(9) 
Timespan.FromHours(10), Timespan.FromHours(15) 

Другое ca себе:

timeRange.Add(new Interval(TimeSpan.FromHours(9), TimeSpan.FromHours(17)) 
timeRange.Add(new Interval(TimeSpan.FromHours(17), TimeSpan.FromHours(19)) 

interval.Add(new Interval(TimeSpan.FromHours(0), TimeSpan.FromHours(4)) 
interval.Add(new Interval(TimeSpan.FromHours(4), TimeSpan.FromHours(5)) 
interval.Add(new Interval(TimeSpan.FromHours(5), TimeSpan.FromHours(9)) 
interval.Add(new Interval(TimeSpan.FromHours(9), TimeSpan.FromHours(10)) 
interval.Add(new Interval(TimeSpan.FromHours(12), TimeSpan.FromHours(13)) 

Ожидаемый результат:

Timespan.FromHours(0), Timespan.FromHours(4) 
Timespan.FromHours(4), Timespan.FromHours(5) 
Timespan.FromHours(5), Timespan.FromHours(9) 
Timespan.FromHours(9), Timespan.FromHours(10) 
Timespan.FromHours(10), Timespan.FromHours(12) 
Timespan.FromHours(12), Timespan.FromHours(13) 
Timespan.FromHours(13), Timespan.FromHours(17) 
Timespan.FromHours(17), Timespan.FromHours(19) 
+0

В чем состоит назначение двух классов, выполняющих ту же работу? Почему вам нужно объединить их в один список? Что вы пробовали? –

+0

Эти два класса представлены по-разному в разных областях. Я должен объединить его, чтобы выполнить некоторую операцию в конечном списке. Моя проблема заключается в том, что в одном списке может быть больше элементов, тогда другие не могли бы определить, какой из них следует перебирать? – King

+0

Какова логика в том, почему у вас есть 5 новых диапазонов от 4? Почему это не 1-5, 6-7, 8-9, 10-15? Это также может быть 1-5, 5-6, 6-7, 7-8, 8-9, 9-10, 10-15, если вы хотите каждый «промежуток времени». Что именно должна ваша конечная логика искать в итоге 5? – wentimo

ответ

0

Поняв я думал об этой проблеме в неправильном направлении, я пришел к подходу, который должен работать в большинстве сценариев. Если вы столкнетесь с некоторыми данными, которые не работают, пожалуйста, предоставьте его мне, и я исправлю это. Благодаря!

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Runtime.CompilerServices; 

namespace ConsoleApplication1 
{ 
    internal class Program 
    { 
     private static void Main(string[] args) 
     { 
      List<TimeRange> timeRanges = new List<TimeRange>(); 
      timeRanges.Add(new TimeRange(TimeSpan.FromHours(2), TimeSpan.FromHours(3))); 
      timeRanges.Add(new TimeRange(TimeSpan.FromHours(8), TimeSpan.FromHours(9))); 
      timeRanges.Add(new TimeRange(TimeSpan.FromHours(1), TimeSpan.FromHours(5))); 
      timeRanges.Add(new TimeRange(TimeSpan.FromHours(3), TimeSpan.FromHours(6))); 

      List<Interval> intervals = new List<Interval>(); 
      intervals.Add(new Interval(TimeSpan.FromHours(1), TimeSpan.FromHours(7))); 
      intervals.Add(new Interval(TimeSpan.FromHours(10), TimeSpan.FromHours(15))); 

      timeRanges.AddRange(intervals.Select(x => new TimeRange(x.start, x.end))); 

      timeRanges = TimeRange.ResolveOverlaps(timeRanges); 

      timeRanges.ForEach(x => Console.WriteLine($"{x.start} - {x.end}")); 
      Console.Read(); 
     } 
    } 

    public class TimeRange 
    { 
     public TimeSpan start { get; set; } 
     public TimeSpan end { get; set; } 

     public TimeRange(TimeSpan st, TimeSpan en) 
     { 
      start = st; 
      end = en; 
     } 

     public static List<TimeRange> ResolveOverlaps(List<TimeRange> timeRanges) 
     { 
      var times = new List<TimeSpan>(); 
      times.AddRange(timeRanges.Select(x => x.start)); 
      times.AddRange(timeRanges.Select(x => x.end)); 
      times = times.Distinct().OrderBy(x => x.Ticks).ToList(); 

      timeRanges.Clear(); 
      while (times.Count > 1) 
      { 
       timeRanges.Add(new TimeRange(times[0], times[1])); 
       times.RemoveAt(0); 
      } 

      return timeRanges; 
     } 

    } 

    public class Interval 
    { 
     public TimeSpan start { get; set; } 
     public TimeSpan end { get; set; } 

     public Interval(TimeSpan st, TimeSpan en) 
     { 
      start = st; 
      end = en; 
     } 
    } 
} 
+0

Благодарим вас за помощь. Однако он работает в некоторых случаях, но он ломается в новых случаях. Спасибо за помощь. – King

+0

Я обновил свой ответ на наиболее надежное решение. Дайте мне знать, если он все еще не работает для вас. – wentimo

+0

Этот подход, похоже, не работает со вторым случаем, о котором я упоминал. Также он ограничивает класс TimeRange и Interval только наличием только двух свойств. – King

Смежные вопросы