Created
January 23, 2014 16:09
-
-
Save chilversc/8581320 to your computer and use it in GitHub Desktop.
Contiguous segments
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define NONEST | |
void Main() | |
{ | |
Sample1 (); | |
Sample2 (); | |
} | |
void Sample1 () | |
{ | |
var source = new[] { | |
new Range ( 1, 5), | |
new Range ( 6, 10), | |
new Range (12, 15), | |
new Range (17, 20), | |
new Range (21, 25), | |
new Range (26, 30), | |
new Range (31, 35), | |
}; | |
source.ContiguousSegments (IsAdjacent).Dump (); | |
} | |
void Sample2 () | |
{ | |
var source = new[] {1,2,3,4,5,10,11,12,15,20}; | |
source.ContiguousSegments ((a, b) => a + 1 == b).Dump (); | |
} | |
static bool IsAdjacent (Range a, Range b) | |
{ | |
return a.End + 1 == b.Start; | |
} | |
struct Range | |
{ | |
public readonly int Start; | |
public readonly int End; | |
public Range (int start, int end) | |
{ | |
Start = start; | |
End = end; | |
} | |
} | |
public static class EnumerableCoda | |
{ | |
public static IEnumerable<IEnumerable<TSource>> ContiguousSegments<TSource> (this IEnumerable<TSource> source, Func<TSource, TSource, bool> predicate) | |
{ | |
if (source == null) | |
throw new ArgumentNullException ("source"); | |
if (predicate == null) | |
throw new ArgumentNullException ("predicate"); | |
return ContiguousSegmentsIterator (source, predicate); | |
} | |
private static IEnumerable<IEnumerable<TSource>> ContiguousSegmentsIterator<TSource> (IEnumerable<TSource> source, Func<TSource, TSource, bool> predicate) | |
{ | |
using (var e = source.GetEnumerator ()) { | |
if (!e.MoveNext ()) | |
yield break; | |
var group = new List<TSource> (); | |
var previous = e.Current; | |
group.Add (previous); | |
while (e.MoveNext ()) { | |
var current = e.Current; | |
if (!predicate (previous, current)) { | |
yield return group; | |
group = new List<TSource> (); | |
} | |
group.Add (current); | |
previous = current; | |
} | |
yield return group; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment