Question:
There is a method that returns a sequence consisting of pairs of adjacent elements. For example, given the sequence {1,2,3}, the method should return two pairs: (1,2) and (2,3).
The solution that immediately came to mind:
return items
.Take(items.Count() - 1)
.Zip(items.Skip(1), Tuple.Create);
But in this case, IEnumerable is enumerated more than once. How can you solve the problem without multiple enums (keeping the method lazy)?
Answer:
For example, yes. Let's declare an extension method that produces consecutive pairs:
public static class EnumerableExtensions
{
public static IEnumerable<R> Pairwise<T, R>(
this IEnumerable<T> sequence, Func<T, T, R> selector)
{
using (var it = sequence.GetEnumerator())
{
if (!it.MoveNext())
yield break;
T prev = it.Current;
while (it.MoveNext())
yield return selector(prev, prev = it.Current);
}
}
}
And we use:
return items.Pairwise(Tuple.Create);