[英]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.