如何生成动态for循环

时间:2013-08-20 15:11:50

标签: c# loops dynamic for-loop

页面中有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;
                            }

                        }
                    }
                }
            }
        }

2 个答案:

答案 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;
    }
}