function Chunk-Object() { [CmdletBinding()] Param( [Parameter(Mandatory = $true,ValueFromPipeline = $true,ValueFromPipelineByPropertyName = $true)] [object[]] $InputObject,[Parameter()] [scriptblock] $Process,[Parameter()] [int] $ElementsPerChunk ) Begin { $cache = @(); $index = 0; } Process { foreach($o in $InputObject) { $current_element = $o; if($Process) { $current_element = & $Process $current_element; } if($cache.Length -eq $ElementsPerChunk) {,$cache; $cache = @($current_element); $index = 1; } else { $cache += $current_element; $index++; } } } End { if($cache) {,$cache; } } } (Chunk-Object -InputObject (echo 1 2 3 4 5 6 7) -Process {$_ + 100} -ElementsPerChunk 3) Write-Host "------------------------------------------------" (echo 1 2 3 4 5 6 7 | Chunk-Object -Process {$_ + 100} -ElementsPerChunk 3)
结果是:
PS C:\Users\a> C:\Untitled5.ps1 100 100 100 100 100 100 100 ------------------------------------------------ 101 102 103 104 105 106 107 PS C:\Users\a>
解决方法
那么,让我们来看看命令的管道版本:
echo 1 2 3 4 5 6 7 | Chunk-Object -Process {$_ + 100} -ElementsPerChunk 3
这个工作的原因是,对于管道的每次迭代,$_被设置为管道中当前数组元素的值,它也被分配给$InputObject变量(作为单元素数组,由于[object []]类型转换.在这种情况下,foreach循环实际上是无关的,因为$InputObject数组每次调用进程块时总是有一个元素.你实际上可以删除循环并将$current_element = $o更改为$current_element = $InputObject,你会得到完全相同的结果.
现在,让我们检查将数组参数传递给-InputObject的版本:
Chunk-Object -InputObject (echo 1 2 3 4 5 6 7) -Process {$_ + 100} -ElementsPerChunk 3
这不起作用的原因是您传递给-Process参数的scriptblock包含$_,但foreach循环将每个元素分配给$o,并且$_未在任何地方定义.结果中的所有元素都是100,因为每次迭代都会将$current_element设置为scriptblock {$_ 100}的结果,当$_为null时,它总是计算为100.要证明这一点,请尝试将scriptblock中的$_更改为$o,然后您将获得预期的结果:
Chunk-Object -InputObject (echo 1 2 3 4 5 6 7) -Process {$o + 100} -ElementsPerChunk 3
如果您希望能够在scriptblock中使用$_,只需替换foreach($Input in $Input)中的foreach循环(使用$InputObject | %{.这样两个版本都可以工作,因为Chunk-Object函数在内部使用了一个管道,所以$_被顺序设置到数组的每个元素,无论是否为传入的一系列单个数组元素多次调用了进程块作为管道输入,或者只是一次用于多元素阵列.
更新:
我再次看着这个,注意到了这一点
$current_element = & $Process $current_element;
您似乎试图将$current_element作为参数传递给$Process中的scriptblock.这不起作用,因为传递给scriptblock的参数与函数中的参数大致相同.如果你调用MyFunction’foo’,那么’foo’不会自动分配给函数中的$_;同样地,& {$_ 100}’foo’没有将$_设置为’foo’.将您的scriptblock参数更改为{$args [0] 100},无论是否传递管道输入,您都将获得预期的结果:
Chunk-Object -InputObject (echo 1 2 3 4 5 6 7) -Process {$args[0] + 100} -ElementsPerChunk 3
请注意,虽然这个版本的scriptblock参数即使你保留foreach循环也能工作,但我仍然建议使用Foreach-Object($InputObject |%{),因为它通常效率更高,所以函数运行速度更快,大量数据的.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。