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

C# 将两个时间范围列表合并为一个,c#,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(Times

我有一个名为
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)));
另一种情况:

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)

在意识到我对这个问题的想法是错误的之后,我找到了一种在大多数情况下都应该有效的方法。如果你遇到一些数据,这不工作,请提供给我,我会修复它。谢谢

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;
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Runtime.CompilerServices;
命名空间控制台应用程序1
{
内部课程计划
{
私有静态void Main(字符串[]args)
{
列表时间范围=新列表();
添加(新的时间范围(TimeSpan.FromHours(2),TimeSpan.FromHours(3));
添加(新的时间范围(TimeSpan.FromHours(8),TimeSpan.FromHours(9));
添加(新的时间范围(TimeSpan.FromHours(1),TimeSpan.FromHours(5));
添加(新的时间范围(TimeSpan.FromHours(3)、TimeSpan.FromHours(6));
列表间隔=新列表();
添加(新的时间间隔(TimeSpan.FromHours(1),TimeSpan.FromHours(7));
添加(新的时间间隔(TimeSpan.FromHours(10),TimeSpan.FromHours(15));
添加范围(interval.Select(x=>newtimerange(x.start,x.end));
时间范围=时间范围。解析重叠(时间范围);
timeRanges.ForEach(x=>Console.WriteLine($“{x.start}-{x.end}”);
Console.Read();
}
}
公共类时间范围
{
公共时间跨度开始{get;set;}
公共时间跨度结束{get;set;}
公共时间范围(TimeSpan st、TimeSpan en)
{
开始=st;
end=en;
}
公共静态列表解析重叠(列表时间范围)
{
var times=新列表();
times.AddRange(timeRanges.Select(x=>x.start));
times.AddRange(timeRanges.Select(x=>x.end));
times=times.Distinct().OrderBy(x=>x.Ticks.ToList();
timeRanges.Clear();
而(times.Count>1)
{
添加(新的时间范围(时间[0],时间[1]);
移除次数(0);
}
返回时间范围;
}
}
公课间隔
{
公共时间跨度开始{get;set;}
公共时间跨度结束{get;set;}
公共间隔(时间间隔st、时间间隔en)
{
开始=st;
end=en;
}
}
}

让两个类做相同的工作的目的是什么?为什么需要将它们合并到一个列表中?你试过什么?这两个类在不同的领域有不同的表现。我必须合并它才能对最终列表执行一些操作。我的问题是,一个列表可以比另一个列表包含更多的元素,因此无法确定要循环哪个元素?为什么从4到5个新的范围?为什么这不是1-5,6-7,8-9,10-15?如果您想要每个“子时间跨度”,它也可以是1-5、5-6、6-7、7-8、8-9、9-10、10-15。你的最终逻辑到底应该搜索什么才能得到5?因为1-7与5-6重叠,因此需要拆分1-5、5-6、6-7。你在找
字典吗?
?谢谢你的帮助。它在某些情况下是有效的,但是,在我的新情况下它会中断。谢谢你的帮助。我更新了我的答案,找到了一个最可靠的解决方案。让我知道,如果它仍然对你不起作用,这个方法似乎对我提到的第二个案例不起作用。此外,它还限制TimeRange和Interval类仅具有两个属性成员。
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;
        }
    }
}