Skip to content

Instantly share code, notes, and snippets.

@ooraini
Last active October 22, 2017 13:08
Show Gist options
  • Save ooraini/667ddec85df2eebd2275f20049ebf2dd to your computer and use it in GitHub Desktop.
Save ooraini/667ddec85df2eebd2275f20049ebf2dd to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Linq;
using MoreLinq;
public static class CartesianExtension
{
public static IEnumerable<TResult> Cartesian<TSource, TResult>(
this IEnumerable<IEnumerable<TSource>> enumerables,
Func<IEnumerable<TSource>, TResult> resultSelector)
{
if (enumerables == null) throw new ArgumentNullException(nameof(enumerables));
if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector));
var enumerators = enumerables
.Select(e => e?.GetEnumerator() ?? throw new ArgumentException("One of the enumerables is null"))
.Pipe(e => e.MoveNext())
.ToArray();
do yield return resultSelector(enumerators.Select(e => e.Current)); while (MoveNext());
foreach (var enumerator in enumerators) enumerator.Dispose();
bool MoveNext()
{
for (var i = enumerators.Length - 1; i >= 0; i--)
{
if (enumerators[i].MoveNext()) return true;
if (i != 0)
{
enumerators[i].Reset();
enumerators[i].MoveNext();
}
}
return false;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment