将两个TimeRanges列表合并为一个

时间:2015-12-24 20:05:14

标签: c#

我有一个名为TimeRange的班级,另一个Interval都有相同的结构

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)

另一个案例:

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)

1 个答案:

答案 0 :(得分: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;
        }
    }
}