Language: C#
Resolving overlaps in a collection of ranges
using System.Collections.Generic; using System.Linq; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace OverlapClipProjectionWithLinq { [TestClass] public class RangeExtensions_Resolve_Tests { private static readonly GenericEqualityComparer<Range> Comparer = new GenericEqualityComparer<Range>((x, y) => x.Begin == y.Begin && x.End == y.End, x => x.Begin.GetHashCode() * x.End.GetHashCode() * 2); [TestMethod] public void given_set_1_to_10_and_set_5_to_15() { var sets = new[] { new Range {Begin = 1, End = 10}, new Range {Begin = 5, End = 15} }; var expected = new[] { new Range {Begin = 1, End = 4}, new Range {Begin = 5, End = 15} }; var empty = sets.Resolve().Except(expected, Comparer); Assert.AreEqual(0, empty.Count()); } [TestMethod] public void given_set_1_to_10_and_set_5_to_15_and_set_16_to_20() { var sets = new[] { new Range {Begin = 1, End = 10}, new Range {Begin = 5, End = 15}, new Range {Begin = 16, End = 20} }; var expected = new[] { new Range {Begin = 1, End = 4}, new Range {Begin = 5, End = 15}, new Range {Begin = 16, End = 20} }; var empty = sets.Resolve().Except(expected, Comparer); Assert.AreEqual(0, empty.Count()); } [TestMethod] public void given_set_1_to_10_and_set_5_to_15_and_set_14_to_20() { var sets = new[] { new Range {Begin = 1, End = 10}, new Range {Begin = 5, End = 15}, new Range {Begin = 14, End = 20} }; var expected = new[] { new Range {Begin = 1, End = 4}, new Range {Begin = 5, End = 13}, new Range {Begin = 14, End = 20} }; var empty = sets.Resolve().Except(expected, Comparer); Assert.AreEqual(0, empty.Count()); } [TestMethod] public void given_set_1_to_10_and_set_5_to_15_and_set_3_to_20() { var sets = new[] { new Range {Begin = 1, End = 10}, new Range {Begin = 5, End = 15}, new Range {Begin = 3, End = 20} }; var expected = new[] { new Range {Begin = 1, End = 2}, new Range {Begin = 3, End = 20} }; var empty = sets.Resolve().Except(expected, Comparer); Assert.AreEqual(0, empty.Count()); } [TestMethod] public void given_set_1_to_10_and_set_5_to_15_and_set_3_to_11() { var sets = new[] { new Range {Begin = 1, End = 10}, new Range {Begin = 5, End = 15}, new Range {Begin = 3, End = 11} }; var expected = new[] { new Range {Begin = 1, End = 2}, new Range {Begin = 3, End = 11}, new Range {Begin = 14, End = 15} }; var empty = sets.Resolve().Except(expected, Comparer); Assert.AreEqual(0, empty.Count()); } } public static class RangeExtensions { public static IEnumerable<Range> Resolve(this IEnumerable<Range> ranges) { return from set in ranges let hasWrapper = ranges.Any(x => x.Begin <= set.Begin && x.End >= set.End) let overlap = ranges.OrderBy(x => x.Begin).FirstOrDefault(x => x.Begin > set.Begin && x.Begin < set.End) where hasWrapper == false select new Range { Begin = set.Begin, End = overlap == null ? set.End : overlap.Begin - 1 }; } } public class Range { public int Begin { get; set; } public int End { get; set; } } }
Tags:
Description:
I thought this was going to a pain... much easier than I thought
Report Abuse
Subscribe
Discuss
What's new
What is it
New Snippet
Recent Snippets
My Snippets
Web Code
Search

