简体   繁体   English

将两个时间范围列表合并为一个

[英]Merge two list of TimeRanges into one

I have a class named TimeRange and another Interval both have same following structure 我有一个名为TimeRange的类,另一个Interval都具有相同的以下结构

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

I have two list 我有两个清单

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)));

I want to merge these lists into one so that final result will contain this 我想将这些列表合并为一个,以便最终结果将包含此列表

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)

Another case: 另一种情况:

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))

Expected Result: 预期结果:

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)

After realizing I was thinking about this problem in the wrong way I came to an approach that should work in most scenarios. 在意识到之后,我以错误的方式思考了这个问题,我想到了一种在大多数情况下都应该起作用的方法。 If you come across some data that this doesn't work on please provide it to me and I'll fix it. 如果您发现一些无法使用的数据,请提供给我,我会解决。 Thanks! 谢谢!

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;
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM