CodePaste Logo
New Snippet New Snippet Recent Snippets Recent Snippets My Snippets My Snippets Web Code Search Snippets Search
Sign inor Register
Language: C#

Resolving overlaps in a collection of ranges

132 Views
Copy Code Show/Hide Line Numbers
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; }
    }
}
by cromwellryan
  March 30, 2010 @ 10:12pm
Tags:
Description:
I thought this was going to a pain... much easier than I thought

Add a comment


Report Abuse
brought to you by:
West Wind Techologies



If you find this site useful and use it frequently please consider making a donation to support this free service.
Donate