我正在编写一些代码来弄清楚如何将值列表分成更易于管理的块。我想这样做的原因是因为我将拥有大约100,000个实时值,并且我希望最大限度地降低失败风险。
$wholeList = 1..100
$nextStartingPoint
$workingList
function Get-NextTenItems()
{
$workingList = (1+$nextStartingPoint)..(10+$nextStartingPoint)
$nextStartingPoint += 10
Write-Host "inside Get-NextTenItems"
write-host "Next StartingPoint: $nextStartingPoint"
$workingList
Write-Host "exiting Get-NextTenItems"
}
function Write-ListItems()
{
foreach ($li in $workingList)
{
Write-Host $li
}
}
Get-NextTenItems
Write-ListItems
Get-NextTenItems
Write-ListItems
我在PowerGUI调试器中运行了代码,当我退出Get-NextTenItems函数时,我注意到我的$ nextStartingPoint重置为0。
为什么会发生这种情况,我该如何预防呢?
我是否还应该假设$ workingList发生了同样的事情?
答案 0 :(得分:3)
我的建议是使用管道。一个函数产生块,另一个函数消耗它们。
使用这种方法,您不需要污染全局/脚本范围,这不是一个好主意。所需的一切都保存在需要它的功能中。
function Get-Chunk
{
param(
[Parameter(Mandatory=$true)]$collection,
[Parameter(Mandatory=$false)]$count=10
)
#temporary array
$tmp = @()
$i = 0
foreach($c in $collection) {
$tmp += $c # add item $c to array
$i++ # increase counter; indicates that we reached chunk size
if ($i -eq $count) {
,$tmp # send the temporary array to the pipeline
$i = 0 # reset variables
$tmp = @()
}
}
if ($tmp) { # if there is something remaining, send it to the pipeline
,$tmp
}
}
function Write-ListItems
{
param(
[Parameter(Mandatory=$true, ValueFromPipeline=$true)]$chunk
)
process {
write-host Chunk: "$chunk"
}
}
测试功能:
$wholeList = 1..100
Get-Chunk $wholeList | Write-ListItems
Chunk: 1 2 3 4 5 6 7 8 9 10
Chunk: 11 12 13 14 15 16 17 18 19 20
Chunk: 21 22 23 24 25 26 27 28 29 30
Chunk: 31 32 33 34 35 36 37 38 39 40
Chunk: 41 42 43 44 45 46 47 48 49 50
Chunk: 51 52 53 54 55 56 57 58 59 60
Chunk: 61 62 63 64 65 66 67 68 69 70
Chunk: 71 72 73 74 75 76 77 78 79 80
Chunk: 81 82 83 84 85 86 87 88 89 90
Chunk: 91 92 93 94 95 96 97 98 99 100
Get-Chunk $wholeList 32 | Write-ListItems
Chunk: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
Chunk: 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
Chunk: 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
Chunk: 97 98 99 100
<强>更新强>
我添加了一些评论以澄清事情。注意,当向管道发送内容时(a)我不使用return
,因为我会从函数中跳出来。 (b)开头的逗号将$tmp
的内容包装到数组中,因此它创建一个包含一个项目的新数组(这是N个项目的数组)。为什么?因为在PowerShell中有自动展开,这将从数组中解开项目并将所有项目展平 - &gt;结果将是一个大阵列。
示例:
function Get-Arrays {
1,2,3
"a", "b"
,(get-date)
4,5,6
}
Get-Arrays | % { "$_" }
这可以按预期工作:
function Get-Arrays {
,(1,2,3)
,("a", "b")
,(get-date)
,(4,5,6)
}
Get-Arrays | % { "$_" }
答案 1 :(得分:2)
在您的示例Get-NextTenItems
中更改其本地变量。有几种方法可以解决此问题,其中有两种方法:
1)明确指定变量范围(使用前缀script
或global
)。也就是说,在函数内使用变量$script:nextStartingPoint
,$script:workingList
。
2)更改其通话中的功能范围。即,使用点运算符(“dot-source”函数)调用函数,即在当前作用域中执行它。此代码按预期工作(无需其他更改):
. Get-NextTenItems
Write-ListItems
. Get-NextTenItems
Write-ListItems
另见
help about_scopes
答案 2 :(得分:1)
前面的答案还可以。但它不完整,它允许你以某种方式编码不可读。在纯粹的编程观点上,您还有另外两种方法可以将参数传递给过程(或函数),其中一种方法允许您修改参数。
<强> 1。按值的参数(常见方式)
使用这种方式记录函数使用的参数
Function addition ([int]$x, [int]$y) {
$x + $y
}
<强> 2。参数参数(通过引用调用一种指针)
使用这种方式,最后一个参数可以修改为你的函数。
function addition ([int]$x, [int]$y, [ref]$R) {
$Res = $x * $y
$R.value = $Res
}
# usage
addition $A $B ([ref]$C)
在使用第二个解决方案的代码中:
我希望它有所帮助。