Skip to content

Instantly share code, notes, and snippets.

@tomaustin700
Created April 18, 2018 07:12
Show Gist options
  • Save tomaustin700/96216c53b1e56783243e9200f4c93ab0 to your computer and use it in GitHub Desktop.
Save tomaustin700/96216c53b1e56783243e9200f4c93ab0 to your computer and use it in GitHub Desktop.
Extension method for generating a Cartesian product
public static class ListExtentions
{
public static IEnumerable Cartesian(this IEnumerable<IEnumerable> items)
{
var slots = items
// initialize enumerators
.Select(x => x.GetEnumerator())
// get only those that could start in case there is an empty collection
.Where(x => x.MoveNext())
.ToArray();
while (true)
{
// yield current values
yield return slots.Select(x => x.Current);
// increase enumerators
foreach (var slot in slots)
{
// reset the slot if it couldn't move next
if (!slot.MoveNext())
{
// stop when the last enumerator resets
if (slot == slots.Last()) { yield break; }
slot.Reset();
slot.MoveNext();
// move to the next enumerator if this reseted
continue;
}
// we could increase the current enumerator without reset so stop here
break;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment