如果有两个以上的项目,以下代码将打印计数。 .Split(',')
被调用了两次。
'a,b,c', 'x,y', '1,2,3' |
Where-Object { $_.Split(',').Count -gt 2 } |
ForEach-Object { $x = $_.Split(','); $x.Count }
以下代码尝试一次调用
.Split(',')
。它没有任何输出。'a,b,c', 'x,y', '1,2,3' |
ForEach-Object { @($_.Split(',')) } | # got a single list instead of `list of list of string`
Where-Object { $_.Count -gt 2 } |
ForEach-Object { $_.Count }
但是,
ForEach-Object
使list of list
变平以列出。这是防止扁平化的方法吗? 最佳答案
您可以利用Where-Object
和ForEach-Object
都在同一范围(调用者的范围)中运行传递给它们的脚本块({ ... }
)的事实:
'a,b,c', 'x,y', '1,2,3', 'a,b,c,d' |
Where-Object { ($count = $_.Split(',').Count) -gt 2 } |
ForEach-Object { $count }
即,在
$count
脚本块中也可以通过输入对象逐个访问在Where-Object
脚本块中分配的ForEach-Object
变量。就是说,您可以仅使用
ForEach-Object
来完成所有需要的工作:'a,b,c', 'x,y', '1,2,3', 'a,b,c,d' |
ForEach-Object { $count = ($_ -split ',').Count; if ($count -gt 2) { $count } }
请注意,我已经从
.Split()
方法切换为使用PowerShell的more flexible -split
运算符。至于您尝试了什么:
向管道输出数组(可枚举)会导致其元素被一一发送,而不是整个数组。
避免这种情况的最简单方法,即整体发送一个数组,是使用一元形式
,
(数组构造运算符:, $_.Split(',')
)将此类数组包装在辅助单元素包装器数组中请注意,将命令包含在
@(...)
中的不会执行相同的包装,因为 @(...)
不会构造数组。松散地说,它仅确保输出是一个数组,因此,如果输入已经是一个数组-如您的情况-@(...)
是-松散地说-一个(昂贵的)无操作-有关详细信息,请参见this answer的底部。