There is another quite interesting solution that I'm aware of. It's interesting mostly from educational perspective but if one needs to perform zipping different counts of lists A LOT, then it also might be useful.
This method overrides .NET's LINQ SelectMany
function which is taken by a convention when you use LINQ's query syntax. The standard SelectMany
implementation does a Cartesian Product. The overrided one can do zipping instead. The actual implementation could be:
static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(this IEnumerable<TSource> source,
Func<TSource, IEnumerable<TCollection>> selector, Func<TSource, TCollection, TResult> select)
{
using (var e1 = source.GetEnumerator())
using (var e2 = selector(default(TSource)).GetEnumerator())
while (true)
if (e1.MoveNext() && e2.MoveNext())
yield return select(e1.Current, e2.Current);
else
yield break;
}
It looks a bit scary but it is a logic of zipping which if written once, can be used in many places and the client's code look pretty nice - you can zip any number of IEnumerable<T>
using standard LINQ query syntax:
var titles = new string[] { "Analyst", "Consultant", "Supervisor"};
var names = new string[] { "Adam", "Eve", "Michelle" };
var surnames = new string[] { "First", "Second", "Third" };
var results =
from title in titles
from name in names
from surname in surnames
select $"{ title } { name } { surname }";
If you then execute:
foreach (var result in results)
Console.WriteLine(result);
You will get:
Analyst Adam First
Consultant Eve Second
Supervisor Michelle Third
You should keep this extension private within your class because otherwise you will radically change behavior of surrounding code. Also, a new type will be useful so that it won't colide with standard LINQ behavior for IEnumerables.
For educational purposes I've created once a small c# project with this extension method + few benefits: https://github.com/lukiasz/Zippable
Also, if you find this interesting, I strongly recommend Jon Skeet's Reimplementing LINQ to Objects articles.
Have fun!