Dykam's mention of Zip led me to this:
public static class EnumerableExtensions
{
public delegate bool EqualityComparison<in T1, in T2>(T1 x, T2 y);
public delegate bool EqualityComparison<in T>(T x, T y);
public static IEnumerable<T> CommonPrefix<T>(
this IEnumerable<T> xs,
IEnumerable<T> ys)
{
return CommonPrefix(xs, ys, EqualityComparer<T>.Default.Equals);
}
public static IEnumerable<T> CommonPrefix<T>(
this IEnumerable<T> xs,
IEnumerable<T> ys,
EqualityComparison<T1, T2> eq)
{
IEnumerator<T> x = xs.GetEnumerator();
IEnumerator<T> y = ys.GetEnumerator();
while (x.MoveNext() && y.MoveNext() && eq(x.Current, y.Current))
{
yield return x.Current;
}
}
public static IEnumerable<TResult> CommonPrefix<T1, T2, TResult> (
this IEnumerable<T1> xs,
IEnumerable<T2> ys,
EqualityComparison<T1, T2> eq,
Func<T1, T2, TResult> selector)
{
IEnumerator<T1> x = xs.GetEnumerator();
IEnumerator<T2> y = ys.GetEnumerator();
while (x.MoveNext() && y.MoveNext() && eq(x.Current, y.Current))
{
yield return selector(x.Current, y.Current);
}
}
}