Давайте начнем с обобщенного Cartesian
:
private static IEnumerable<T[]> Cartesian<T>(IEnumerable<IEnumerable<T>> source) {
T[][] lists = source
.Select(line => line.ToArray())
.ToArray();
if (source.Any(line => !line.Any()))
yield break;
int[] indexes = new int[lists.Length];
do {
yield return lists.Select((line, index) => line[indexes[index]]).ToArray();
for (int i = 0; i < indexes.Length; ++i)
if (++indexes[i] < lists[i].Length)
break;
else
indexes[i] = 0;
}
while (!indexes.All(index => index == 0));
}
Тогда мы можем попробовать использовать его.Давайте организуем все коллекции, которые мы хотим запросить, в один словарь :
// we allow to use any IEnumerable<string>, not necessary List<string>
Dictionary<string, IEnumerable<string>> data =
new Dictionary<string, IEnumerable<string>>(StringComparer.OrdinalIgnoreCase) {
{ "Gender", new [] { "M", "F" } },
{ "Age", new List<string> { "10-15", "16-20", "21-26" } },
{ "City", new [] { "CityA", "CityB" } },
};
и запросим его:
string userChoice = "gender_city_age";
var result = Cartesian(userChoice.Split('_').Select(name => data[name]));
// Have a look at the result:
string report = string.Join(Environment.NewLine, result
.Select(line => string.Join(", ", line)));
Console.Write(report);
Результат:
M, CityA, 10-15
F, CityA, 10-15
M, CityB, 10-15
F, CityB, 10-15
M, CityA, 16-20
F, CityA, 16-20
M, CityB, 16-20
F, CityB, 16-20
M, CityA, 21-26
F, CityA, 21-26
M, CityB, 21-26
F, CityB, 21-26