Powershell PSObject 基于另一个 属性 计算 属性
Powershell PSObject calculated property based on another property
我正在创建一个具有计算属性的 PSObject 数组。我需要一个 属性 是根据同一对象的 另一个 属性 计算出来的。我怎么做?
示例 - 假设我有字符串数组,如“a_1”、“b_2”、“c_3”等,并且我有一个基于 return 的查找函数在这些字符串的第一部分,即 someLookUpFunction('a')
将 return “AA” 输入“a”。
现在我的对象中需要一个 属性,它根据我的 'name' 属性
计算出 'AA'
$stringArray = @('a_1', 'b_2', 'c_3')
$objectArray = $stringArray | ForEach-Object{
New-Object PSObject -Property @{
'name' = ($_ -split "_")[0]
'extendedName' = {$name = ($_ -split "_")[0]; someLookUpFunction($name) }
}
}
上面的代码部分不起作用,因为 'extendedName' 属性 的输出只是这个脚本块。如何让它取值?
如果需要在表达式中捕获表达式的输出,可以使用子表达式运算符 $()
.
$stringArray = @('a_1', 'b_2', 'c_3')
$objectArray = $stringArray | ForEach-Object {
[pscustomobject]@{
'name' = ($_ -split "_")[0]
# You can't reference the name property above in this property because it has not been created yet.
'extendedName' = $($name = ($_ -split "_")[0]; someLookUpFunction $name)
}
}
但是,在您的示例中,这不是必需的。您可以在自定义对象创建之前定义一个变量,然后在对象创建代码中引用它:
$stringArray = @('a_1', 'b_2', 'c_3')
$objectArray = $stringArray | ForEach-Object {
$name = ($_ -split '_')[0]
[pscustomobject]@{
'name' = $name
'extendedName' = someLookUpFunction $name
}
}
您也可以直接将表达式传递给参数,前提是它可以被正确标记化:
$stringArray = @('a_1', 'b_2', 'c_3')
$objectArray = $stringArray | ForEach-Object {
[pscustomobject]@{
'name' = ($_ -split '_')[0]
'extendedName' = someLookUpFunction ($_ -split '_')[0]
}
}
注意: 如果启用了位置参数,则不使用管道调用函数的正确方法是 functionName -parametername parametervalue
或 functionName parametervalue
。语法 functionName(parametervalue)
可能会产生意想不到的后果。请参阅 以深入了解 function/method 调用语法。
在对象创建之前,您无法访问该对象的 name
属性。
除了 之外,您还可以使用带有计算的 属性 哈希语法的 select 语句完全绕过循环:
$stringArray = @('a_1', 'b_2', 'c_3')
$objectArray = $stringArray |
Select-Object @{Name = 'Name'; Expression = { ($_ -Split '_')[0] } },
@{Name = 'ExtendedName'; Expression = { SomeLookupFunction ($_ -Split '_')[0] } }
为了不执行 -Split '_'
2x 的效率,如果你确实使用循环,只需使用变量和引用两次。
AdminOfThings 示例的更改版本:
$stringArray = @('a_1', 'b_2', 'c_3')
$objectArray = $stringArray | ForEach-Object {
$TmpName = ($_ -split '_')[0]
[pscustomobject]@{
'name' = $TmpName
'extendedName' = someLookUpFunction $TmpName
}
}
在 属性 添加到对象之前不能引用它也是正确的。解决这个问题的一种方法是只使用 2 select 语句:
$stringArray = @('a_1', 'b_2', 'c_3')
$objectArray = $stringArray |
Select-Object @{Name = 'Name'; Expression = { ($_ -Split '_')[0] } } |
Select-Object *, @{Name = 'ExtendedName'; Expression = { SomeLookupFunction ($_ -Split '_')[0] } }
这可能有一些可读性优势,但是,我尽量避免它,以支持调用尽可能少的命令。
我正在创建一个具有计算属性的 PSObject 数组。我需要一个 属性 是根据同一对象的 另一个 属性 计算出来的。我怎么做?
示例 - 假设我有字符串数组,如“a_1”、“b_2”、“c_3”等,并且我有一个基于 return 的查找函数在这些字符串的第一部分,即 someLookUpFunction('a')
将 return “AA” 输入“a”。
现在我的对象中需要一个 属性,它根据我的 'name' 属性
$stringArray = @('a_1', 'b_2', 'c_3')
$objectArray = $stringArray | ForEach-Object{
New-Object PSObject -Property @{
'name' = ($_ -split "_")[0]
'extendedName' = {$name = ($_ -split "_")[0]; someLookUpFunction($name) }
}
}
上面的代码部分不起作用,因为 'extendedName' 属性 的输出只是这个脚本块。如何让它取值?
如果需要在表达式中捕获表达式的输出,可以使用子表达式运算符 $()
.
$stringArray = @('a_1', 'b_2', 'c_3')
$objectArray = $stringArray | ForEach-Object {
[pscustomobject]@{
'name' = ($_ -split "_")[0]
# You can't reference the name property above in this property because it has not been created yet.
'extendedName' = $($name = ($_ -split "_")[0]; someLookUpFunction $name)
}
}
但是,在您的示例中,这不是必需的。您可以在自定义对象创建之前定义一个变量,然后在对象创建代码中引用它:
$stringArray = @('a_1', 'b_2', 'c_3')
$objectArray = $stringArray | ForEach-Object {
$name = ($_ -split '_')[0]
[pscustomobject]@{
'name' = $name
'extendedName' = someLookUpFunction $name
}
}
您也可以直接将表达式传递给参数,前提是它可以被正确标记化:
$stringArray = @('a_1', 'b_2', 'c_3')
$objectArray = $stringArray | ForEach-Object {
[pscustomobject]@{
'name' = ($_ -split '_')[0]
'extendedName' = someLookUpFunction ($_ -split '_')[0]
}
}
注意: 如果启用了位置参数,则不使用管道调用函数的正确方法是 functionName -parametername parametervalue
或 functionName parametervalue
。语法 functionName(parametervalue)
可能会产生意想不到的后果。请参阅
在对象创建之前,您无法访问该对象的 name
属性。
除了
$stringArray = @('a_1', 'b_2', 'c_3')
$objectArray = $stringArray |
Select-Object @{Name = 'Name'; Expression = { ($_ -Split '_')[0] } },
@{Name = 'ExtendedName'; Expression = { SomeLookupFunction ($_ -Split '_')[0] } }
为了不执行 -Split '_'
2x 的效率,如果你确实使用循环,只需使用变量和引用两次。
AdminOfThings 示例的更改版本:
$stringArray = @('a_1', 'b_2', 'c_3')
$objectArray = $stringArray | ForEach-Object {
$TmpName = ($_ -split '_')[0]
[pscustomobject]@{
'name' = $TmpName
'extendedName' = someLookUpFunction $TmpName
}
}
在 属性 添加到对象之前不能引用它也是正确的。解决这个问题的一种方法是只使用 2 select 语句:
$stringArray = @('a_1', 'b_2', 'c_3')
$objectArray = $stringArray |
Select-Object @{Name = 'Name'; Expression = { ($_ -Split '_')[0] } } |
Select-Object *, @{Name = 'ExtendedName'; Expression = { SomeLookupFunction ($_ -Split '_')[0] } }
这可能有一些可读性优势,但是,我尽量避免它,以支持调用尽可能少的命令。