有条件地替换PowerShell对象中的值

有条件地替换PowerShell对象中的值,powershell,foreach,pscustomobject,Powershell,Foreach,Pscustomobject,我有一个PSCustomObject数组,包含在名为$attention的变量中 event name date present ----- ---- ---- ------- A01 Mika 2021-02-22 1 A01 John 2021-02-22 0 B03 Mika 2021-02-24 0 B03 John 2021-02-24 1 必须将present列值修改为以下值: event name date present --

我有一个PSCustomObject数组,包含在名为
$attention
的变量中

event name date       present
----- ---- ----       -------
A01   Mika 2021-02-22 1
A01   John 2021-02-22 0
B03   Mika 2021-02-24 0
B03   John 2021-02-24 1
必须将
present
列值修改为以下值:

event name date       present
----- ---- ----       -------
A01   Mika 2021-02-22 Yes
A01   John 2021-02-22 No
B03   Mika 2021-02-24 No
B03   John 2021-02-24 Yes
我可以使用
ForEach对象
循环来更改它,但这会迭代整个对象

$attendance | 
   ForEach-Object { 
      if ($_.present -eq '1') { $_.present = 'Yes' } else {$_.present = 'No' } 
   }
为了缩短代码,我尝试了以下的变体,但无法将其折叠回
$attention
变量

$attendance.present.replace('1','Yes').replace('0','No')

是否有一种使用点符号的单行或更简单的方法来更改
present
列的值?

通过使用
Replace()
方法,您只是在操作present中存储的字符串,它不会更新
$attention
上的值,也没有字符串方法来执行此操作。

通过使用
Replace()
方法,您只是在操作存储在present中的字符串,它不会更新
$attention
上的值,也没有string方法可以做到这一点。

我不知道如何在不使用循环的情况下更新所有值,但是您可以将代码缩短为

$attendance | % {$_.present = @('Yes', 'No')[$_.present -eq '0']}
另一个选项可能是添加自定义属性进行转换

$attendance | 
    Add-Member -Name 'yesno' -MemberType ScriptProperty -Value {
        return  @('Yes', 'No')[$this.present -eq '0']
    }
示例请注意,我的csv分隔符是逗号,因此请相应更改


我不知道如何在不使用循环的情况下更新所有值,但是您可以将代码缩短为

$attendance | % {$_.present = @('Yes', 'No')[$_.present -eq '0']}
另一个选项可能是添加自定义属性进行转换

$attendance | 
    Add-Member -Name 'yesno' -MemberType ScriptProperty -Value {
        return  @('Yes', 'No')[$this.present -eq '0']
    }
示例请注意,我的csv分隔符是逗号,因此请相应更改


另一种方法是在以下情况下使用
选择对象

$attendance | Select-Object *, @{Name = 'present'; Expression = {('No','Yes')[[math]::Sign($_.present)]}} -ExcludeProperty present
输出:

event name date       present
----- ---- ----       -------
A01   Mika 2021-02-22 Yes    
A01   John 2021-02-22 No     
B03   Mika 2021-02-24 No     
B03   John 2021-02-24 Yes

另一种方法是在以下情况下使用
选择对象

$attendance | Select-Object *, @{Name = 'present'; Expression = {('No','Yes')[[math]::Sign($_.present)]}} -ExcludeProperty present
输出:

event name date       present
----- ---- ----       -------
A01   Mika 2021-02-22 Yes    
A01   John 2021-02-22 No     
B03   Mika 2021-02-24 No     
B03   John 2021-02-24 Yes

不幸的是,使用点表示法,如
$attention.present
会创建一个新数组,该数组不能用于操作
PSCustomObject
的原始数组

我能想出的最短答案是:

$attendance.foreach({ $_.present = ('No', 'Yes')[ $_.present ] })
无论
present
是整数还是字符串,这都有效。PowerShell在用于索引数组时会自动将字符串转换为整数

稍长一点,使用(需要PS7+):


我更喜欢后者,因为我认为后者更容易阅读。

不幸的是,使用了点符号,如
$attention.present
创建了一个新数组,不能用于操作
PSCustomObject
的原始数组

我能想出的最短答案是:

$attendance.foreach({ $_.present = ('No', 'Yes')[ $_.present ] })
无论
present
是整数还是字符串,这都有效。PowerShell在用于索引数组时会自动将字符串转换为整数

稍长一点,使用(需要PS7+):

我更喜欢后者,因为我认为后者更容易阅读