簡體   English   中英

如何生成動態for循環

[英]How to generate 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;
                            }

                        }
                    }
                }
            }
        }

您想要做的事情可以被視為未知數量(在編譯時)序列的笛卡爾積。

埃里克·利珀特(Eric Lippert)寫了一篇博客文章,介紹如何在C#中創建這樣的解決方案。 他最終生成的代碼是:

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));
}

我將指導您了解Eric Lippert的精彩文章 ,內容涉及如何在Linq中實現笛卡爾乘積 ,他將其寫為通用 擴展方法

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM