如何解决Powershell函数从管道接收多个参数
我正在编写如下函数:
Function display-ItemLocation {
Param(
[ Parameter (
Mandatory = $True,Valuefrompipeline = $True ) ]
[ String ]$stringItem,[ Parameter (
Mandatory = $False,Valuefrompipeline = $True ) ]
[ String ]$stringLocation = 'unkNown'
)
Echo "The location of item $stringItem is $stringLocation."
}
display-ItemLocation 'Illudium Q-36 Explosive Space Modulator' 'Mars'
display-ItemLocation 'Plumbus'
它可以正常工作。
The location of item Illudium Q-36 Explosive Space Modulator is Mars.
The location of item Plumbus is unkNown.
我希望能够预加载具有多个数据对的数组,并通过管道将其发送到函数中。
$Data = @(
@('Bucket','Aisle 1'),@('Spinach Pie','Freezer 4')
)
$Data | display-ItemLocation
我找不到使它正常工作的神奇语法。函数可以从管道中同时接受一对值吗?
解决方法
使用属性 -ValuefromPipelineByPropertyName
-将管道绑定参数定义为绑定,然后管道(自定义)具有这些属性的对象 :
Function Display-ItemLocation {
Param(
[ Parameter (
Mandatory,ValuefromPipelineByPropertyName ) ]
[ String ]$stringItem,[ Parameter (
Mandatory = $False,ValuefromPipelineByPropertyName ) ]
[ String ]$stringLocation = 'unknown'
)
process { # !! You need a `process` block to process *all* input objects.
Echo "The location of item $stringItem is $stringLocation."
}
}
顺便说一句:Display
在PowerShell中不是approved verb。
现在,您可以通过以下方式传递给该函数;请注意,属性名称必须与参数名称匹配:
$Data = [pscustomobject] @{ stringItem = 'Bucket'; stringLocation = 'Aisle 1' },[pscustomobject] @{ stringItem = 'Spinach Pie'; stringLocation = 'Freezer 4' }
$Data | Display-ItemLocation
以上结果:
The location of item Bucket is Aisle 1.
The location of item Spinach Pie is Freezer 4.
-
以上使用了
[pscustomobject]
个实例,这些实例很容易就可以临时构建。- 请注意, 哈希表 (例如,仅
@{ stringItem = 'Bucket'; stringLocation = 'Aisle 1' }
)不起作用-尽管this GitHub issue中正在讨论的更改。
- 请注意, 哈希表 (例如,仅
-
在PSv5 +中,您可以定义自定义
class
:
# Define the class.
class Product {
[string] $stringItem
[string] $stringLocation
Product([object[]] $itemAndLocation) {
$this.stringItem = $itemAndLocation[0]
$this.stringLocation = $itemAndLocation[1]
}
}
# Same output as above.
[Product[]] (
('Bucket','Aisle 1'),('Spinach Pie','Freezer 4')
) | Display-ItemLocation
,
感谢@ mklement0将我引向这个解决方案。我想出了两个选择来解决使用数组的困境。
选项1 :使用.ForEach
以通常的方式传递参数。
$Data = @(
@('Bucket',@('Spinach Pie','Freezer 4')
)
$Data.ForEach({Format-ItemLocation "$($_[0])" "$($_[1])"})
选项2 :我使用管道(这是我所追求的),将功能修改为mklement0,建议启用ValuefromPipelineByPropertyName
并包含Process { }
块
Function Format-ItemLocation {
Param (
[ Parameter (
Mandatory = $True,ValuefromPipelineByPropertyName = $True ) ]
[ String ]$stringItem,[ Parameter (
Mandatory = $False,ValuefromPipelineByPropertyName = $True ) ]
[ String ]$stringLocation = 'unknown'
)
Process {
"The location of item $stringItem is $stringLocation."
}
}
我将数组通过管道传递到中间步骤,以将参数名称分配给[PSCustomObject]
。这极大地减少了代码的文本量,这也是我一直在寻找更优雅的解决方案的原因。
$Data = @(
@('Bucket','Freezer 4')
)
$Data |
ForEach-Object { [PSCustomObject]@{stringItem=$_[0];stringLocation=$_[1]} } |
Format-ItemLocation
我已根据建议将函数名称更改为Format-*
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。