StackOverflow: Cartesian Product + N x M Dynamic Array
Credit: Eric Lippert
Sample code (C#, console app)
namespace CartesianStudy{
using System;
using System.Collections.Generic;
using System.Linq;
public static class Program
{
public static void Main()
{
var persons = new[]
{
"Peter",
"Mary",
"Ivan",
"Oscar",
"Lucy"
};
var flyingDays = new List<string>
{
"Tue",
"Wed",
"Fri",
};
var flights = new List<Flight>
{
new Flight("Air Canada", "AC1152"),
new Flight("CanJet", "C6785"),
new Flight("WestJet", "WS4040"),
new Flight("SunWing", "WG423"),
new Flight("Air Canada", "AC093"),
new Flight("American Airlines", "AA8118"),
};
var allCombinations = new IEnumerable<object>[]
{
persons, flyingDays, flights
}.CartesianProduct().ToList();
foreach (var combination in allCombinations
.Select(c => c.ToList()))
{
Console.WriteLine(
"{0} on {1} by {2}",
combination[0],
combination[1],
combination[2]);
}
Console.WriteLine(
"\nCount: {0}\nAny key...",
allCombinations.Count);
Console.ReadKey();
}
private static IEnumerable<IEnumerable<T>>
CartesianProduct<T>(
this IEnumerable<IEnumerable<T>> sequences)
{
IEnumerable<IEnumerable<T>> emptyProduct = new[]
{
Enumerable.Empty<T>()
};
return sequences.Aggregate(
emptyProduct,
(accumulator, sequence) =>
from accseq in accumulator
from item in sequence
select accseq.Concat(new[] { item }));
}
}
public class Flight
{
public string Company { get; set; }
public string Number { get; set; }
public Flight(string company, string number)
{
this.Company = company;
this.Number = number;
}
public override string ToString()
{
return string.Format(
"{0} - {1}",
this.Company,
this.Number);
}
}
}