页面中有5个动态创建的级联组合框。 当达到预期的总和时,我必须做点什么。这是我生成一些输出的代码;我想动态生成所有for循环甚至所有'cmb'数组。我怎样才能实现它?
private int[] cmb1 = { 0, 2, 4, 6, 8, 12, 16, 20 };
private int[] cmb2 = { 0, 2, 4, 6, 8, 12, 16, 20 };
private int[] cmb3 = { 0, 2, 4, 6, 8, 12, 16, 20 };
private int[] cmb4 = { 0, 2, 4, 6, 8, 12, 16, 20 };
private int[] cmb5 = { 0, 2, 4, 6, 8, 12, 16, 20 };
int count = 0;
for (int i = 0; i < cmb1.Length; i++)
{
for (int j = 0; j < cmb2.Length; j++)
{
for (int k = 0; k < cmb3.Length; k++)
{
for (int l = 0; l < cmb4.Length; l++)
{
for (int m = 0; m < cmb5.Length; m++)
{
if (cmb1[i] + cmb2[j] + cmb3[k] + cmb4[l] + cmb5[m] <= 20 && (i + j + k + l + m) != 0)
{
Console.WriteLine(count + " _ " + i + " " + j + " " + k + " " + l + " " + m);
count = count + 1;
}
}
}
}
}
}
答案 0 :(得分:2)
您要查看的内容可以被视为未知(编译时)序列数的笛卡尔积。
Eric Lippert写了一篇关于如何在C#中创建这样一个解决方案的blog post。他最终生成的代码是:
public 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 }));
}
使用这个我们现在可以做到:
List<int[]> cmbs = new List<int[]>();
cmbs.Add(new int[] { 0, 2, 4, 6, 8, 12, 16, 20 });
cmbs.Add(new int[] { 0, 2, 4, 6, 8, 12, 16, 20 });
cmbs.Add(new int[] { 0, 2, 4, 6, 8, 12, 16, 20 });
var query = cmbs.CartesianProduct()
.Where(combo => combo.Sum() <= 20 && combo.Sum() > 0);
int count = 0;
foreach (var combo in query)
{
Console.Write((count++) + " _ ");
Console.WriteLine(string.Join(" ", combo));
}
答案 1 :(得分:1)
我将引导你{Lin}在Eric Lippert's excellent article Cartesian product generic中执行extension method {{3}}。{/ 3>
static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences)
{
// base case:
IEnumerable<IEnumerable<T>> result = new[] { Enumerable.Empty<T>() };
foreach(var sequence in sequences)
{
var s = sequence; // don't close over the loop variable
// recursive case: use SelectMany to build the new product out of the old one
result =
from seq in result
from item in s
select seq.Concat(new[] {item});
}
return result;
}
所以在你的代码中你会这样称呼它:
private List<int[]> cmbs = new List<int[]>();
...
// build cmbs list
cmbs.Add(cmb1);
cmbs.Add(cmb2);
cmbs.Add(cmb3);
cmbs.Add(cmb4);
cmbs.Add(cmb5);
// loop through cmbs
var count = 0;
foreach(var result in cmbs.CartesianProduct().Skip(1)) // Skip the first result
{
if (result.Sum() <= 20)
{
Console.WriteLine(count + "_" + String.Join(" ", result));
count = count + 1;
}
}