这是一组嵌套的for循环的简单方法,其中最大变量值分别为1、2和3:
for ($i = 0; $i -le 1; $i++)
{
for ($j = 0; $j -le 2; $j++)
{
for ($k = 0; $k -le 3; $k++)
{
"$i $j $k"
}
}
}
我想要一个抽象,用于指示任意数量的嵌套for循环。因此,例如,以上将被调用为:
NestedForLoops (1, 2, 3) { Param($i, $j, $k) "$i $j $k" }
这是一种基于this answer的方法:
function NestedForLoopsAux([int[]]$max_indices, [int[]]$indices, [int]$index, $func)
{
if ($max_indices.Count -eq 0) { &($func) $indices }
else
{
$rest = $max_indices | Select-Object -Skip 1
for ($indices[$index] = 0; $indices[$index] -le $max_indices[0]; $indices[$index]++)
{ NestedForLoopsAux $rest $indices ($index + 1) $func }
}
}
function NestedForLoops([int[]]$max_indices, $func)
{
NestedForLoopsAux $max_indices (@(0) * $max_indices.Count) 0 $func
}
示例调用:
PS C:\> NestedForLoops (1, 2, 3) { Param([int[]]$indices); $i, $j, $k = $indices; "$i $j $k" }
0 0 0
0 0 1
0 0 2
0 0 3
0 1 0
0 1 1
0 1 2
0 1 3
0 2 0
0 2 1
0 2 2
0 2 3
1 0 0
1 0 1
1 0 2
1 0 3
1 1 0
1 1 1
1 1 2
1 1 3
1 2 0
1 2 1
1 2 2
1 2 3
有没有更好的办法?
最佳答案
我不知道这是否更容易,但是您可能会认为这是为您提供更多选择的一种方式。逻辑的核心是构建将用Invoke-Expression
执行的代码字符串。通常只是想看看我是否能做到。
Function New-ForLoopBlock{
Param(
[char]$variableLetter, # {0} Index varialble
[int]$baseIndex, # {1} Base Index Value
[int]$indexMaximum # {2} Max Index Value
)
"for (`${0} = {1}; `${0} -le {2}; `${0}++)" -f $variableLetter,$baseIndex,$indexMaximum
}
Function LoopDeLoop{
Param(
[int[]]$maximums,
[int]$baseIndex = 0
)
# Build a small hashtable with variable and array values.
$values = @{}
For($letterIndex = 0; $letterIndex -lt $maximums.Count; $letterIndex++){
New-Variable -Force -Name [char]($letterIndex + 65)
$values.([char]($letterIndex + 65)) = $maximums[$letterIndex]
}
$nestedLoops = "{}"
# Build the for loop
$nestedLoops = $values.GetEnumerator() | Sort-Object Name | ForEach-Object{
"$(New-ForLoopBlock $_.Name $baseIndex $_.Value){"
}
# The output string this exists inside the loop
$outputString = [string]($values.GetEnumerator() | Sort-Object Name | ForEach-Object{"`$$($_.Name)"})
# Add the output string and closing braces
$nestedLoops = "$nestedLoops`r`n`"$outputString`"`r`n$("}" * $maximums.Count)"
Invoke-Expression $nestedLoops
}
LoopDeLoop
接受2个参数。就像您的整数数组和可选的基值一样。为$maximums
中的每个数组元素创建一些变量(形式为$ a,$ b,....),这些变量将表示每个for循环的索引值。然后使用
$nestedLoops
的输出来创建字符串New-ForLoopBlock
字符串。它不需要是一个函数,而只是返回一个包含for循环语句的字符串。在早期的迭代中,存在更多的逻辑。然后,我们需要构建小的输出字符串。在您的示例中,这是“$ i $ j $ k”。我的是根据创建的变量数量构建的。
在字符串的结尾,我们用大括号关闭
for
循环。 $nestedloops
的示例如下:for ($A = 2; $A -le 3; $A++){ for ($B = 2; $B -le 3; $B++){ for ($C = 2; $C -le 4; $C++){
"$A $B $C"
}}}
就格式化而言,它看起来很糟糕,但是代码具有100%的功能。现在,让我们看一下该函数的一些示例输出:
LoopDeLoop (3,3,4) 2
2 2 2
2 2 3
2 2 4
2 3 2
2 3 3
2 3 4
3 2 2
3 2 3
3 2 4
3 3 2
3 3 3
3 3 4
关于powershell - 嵌套循环抽象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27938366/