ReconcileHelper <T, U, TResult>(EnumerableIterator <T> left, EnumerableIterator <U> right, Func <T, U, int> comparison, Func <T, U, TResult> selector) { while (left.IsValid && right.IsValid) { // While left < right, the items in left aren't in right while (left.IsValid && right.IsValid && comparison(left.Current, right.Current) < 0) { yield return(selector(left.Current, default(U))); left.MoveNext(); } // While right < left, the items in right aren't in left while (left.IsValid && right.IsValid && comparison(left.Current, right.Current) > 0) { yield return(selector(default(T), right.Current)); right.MoveNext(); } // While left == right, the items are in both while (left.IsValid && right.IsValid && comparison(left.Current, right.Current) == 0) { yield return(selector(left.Current, right.Current)); left.MoveNext(); right.MoveNext(); } } // Mop up. while (left.IsValid) { yield return(selector(left.Current, default(U))); left.MoveNext(); } while (right.IsValid) { yield return(selector(default(T), right.Current)); right.MoveNext(); } }
public static void CompareSortedCollections <T>(IEnumerable <T> source, IEnumerable <T> destination, IComparer <T> comparer, Action <T> onLeftOnly, Action <T> onRightOnly, Action <T, T> onBoth) { EnumerableIterator <T> sourceIterator = new EnumerableIterator <T>(source); EnumerableIterator <T> destinationIterator = new EnumerableIterator <T>(destination); while (sourceIterator.HasCurrent && destinationIterator.HasCurrent) { // While LHS < RHS, the items in LHS aren't in RHS while (sourceIterator.HasCurrent && (comparer.Compare(sourceIterator.Current, destinationIterator.Current) < 0)) { onLeftOnly(sourceIterator.Current); sourceIterator.MoveNext(); } // While RHS < LHS, the items in RHS aren't in LHS while (sourceIterator.HasCurrent && destinationIterator.HasCurrent && (comparer.Compare(sourceIterator.Current, destinationIterator.Current) > 0)) { onRightOnly(destinationIterator.Current); destinationIterator.MoveNext(); } // While LHS==RHS, the items are in both while (sourceIterator.HasCurrent && destinationIterator.HasCurrent && (comparer.Compare(sourceIterator.Current, destinationIterator.Current) == 0)) { onBoth(sourceIterator.Current, destinationIterator.Current); sourceIterator.MoveNext(); destinationIterator.MoveNext(); } } // Mop up. while (sourceIterator.HasCurrent) { onLeftOnly(sourceIterator.Current); sourceIterator.MoveNext(); } while (destinationIterator.HasCurrent) { onRightOnly(destinationIterator.Current); destinationIterator.MoveNext(); } }