This is an interesting problem, and to understand it, you need to know what βlawβ is. For the semantics of the operation, I believe that this definition makes sense:
- The source sequence is only listed once, even if the resulting sequences are listed multiple times.
- The original sequence is not listed until one of the results is listed.
- Each of the results should be available for listing independently.
- If the original sequence changes, it is undefined what will happen.
I'm not quite sure that I processed the corresponding object correctly, but I hope that you understand this idea. I set aside a lot of work on the PartitionTuple<T> class to be lazy.
public class PartitionTuple<T> { IEnumerable<T> source; IList<T> before, after; Func<T, bool> partition; public PartitionTuple(IEnumerable<T> source, Func<T, bool> partition) { this.source = source; this.partition = partition; } private void EnsureMaterialized() { if(before == null) { before = new List<T>(); after = new List<T>(); using(var enumerator = source.GetEnumerator()) { while(enumerator.MoveNext() && !partition(enumerator.Current)) { before.Add(enumerator.Current); } while(!partition(enumerator.Current) && enumerator.MoveNext()); while(enumerator.MoveNext()) { after.Add(enumerator.Current); } } } } public IEnumerable<T> Before { get { EnsureMaterialized(); return before; } } public IEnumerable<T> After { get { EnsureMaterialized(); return after; } } } public static class Extensions { public static PartitionTuple<T> Partition<T>(this IEnumerable<T> sequence, Func<T, bool> partition) { return new PartitionTuple<T>(sequence, partition); } }
source share