这里有一组简单的嵌套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
有更好的方法吗?
答案 0 :(得分:1)
我不知道这是否更容易,但你可能会认为这是为你开辟更多选择的一种方式。逻辑的核心是构建将使用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