Hezký den, já bych šel na to úplně jinak. Setřídil bych si intervaly podle začátku "From" a slučoval je. Asi takhle
public static void Main(string[] args)
{
var tr1 = new Timerange {From = new TimeSpan(10, 30, 0), To = new TimeSpan(11, 0, 0)};
var tr2 = new Timerange { From = new TimeSpan(10, 45, 0), To = new TimeSpan(11, 30, 0) };
var tr3 = new Timerange { From = new TimeSpan(12, 45, 0), To = new TimeSpan(13, 0, 0) };
var tr4 = new Timerange { From = new TimeSpan(12, 50, 0), To = new TimeSpan(12, 55, 0) };
var tr5 = new Timerange { From = new TimeSpan(17, 0, 0), To = new TimeSpan(19, 0, 0) };
var ranges = Join(tr3, tr2, tr1, tr5, tr4);
foreach (var s in ranges)
{
Console.WriteLine("{0} - {1}", s.From, s.To);
}
}
private static IEnumerable<Timerange> Join(params Timerange[] timeranges)
{
if (timeranges == null || !timeranges.Any())
return Enumerable.Empty<Timerange>();
var sortedTimeranges = timeranges.OrderBy(x => x.From).ToArray(); // setřídit podle začátku intervalu
var first = sortedTimeranges[0];
var previous = new Timerange {From = first.From, To = first.To};
var resultList = new List<Timerange>();
for (int i = 1 /* nemá smysl zpracovávat první */; i < timeranges.Length; i++)
{
var current = sortedTimeranges[i];
if (current.From <= previous.To && current.To >= previous.From) // lze intervaly sloučit ?
{
if (current.To > previous.To) // a má to smysl ?
previous.To = current.To; // tak je slučme
}
else // nelze sloučit
{
resultList.Add(previous); // vyhodím na výstup
previous = new Timerange {From = current.From, To = current.To}; // začínám s novým intervalem
}
if (i == timeranges.Length - 1) // je poslední, dále se zpracovávat nebude => hodit na výstup
{
resultList.Add(previous);
}
}
return resultList;
}
private class Timerange
{
public TimeSpan From { get; set; }
public TimeSpan To { get; set; }
}
|