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

时间:2021-03-13 07:43:19

标签: powershell foreach pscustomobject

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

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-Object 循环更改它,但这会遍历整个对象。

$attendance | 
   ForEach-Object { 
      if ($_.present -eq '1') { $_.present = 'Yes' } else {$_.present = 'No' } 
   }

为了缩短代码,我尝试了以下变体,但无法将其折叠回 $attendance 变量。

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

是否有使用点表示法更改 present 列值的单行或更简单的方法?

4 个答案:

答案 0 :(得分:2)

另一种可能是在此使用 Select-Object

$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

答案 1 :(得分:1)

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

$attendance | % {$_.present = @('Yes', 'No')[$_.present -eq '0']}

另一种选择可能是添加自定义属性进行转换

$attendance | 
    Add-Member -Name 'yesno' -MemberType ScriptProperty -Value {
        return  @('Yes', 'No')[$this.present -eq '0']
    }

示例 请注意,我的 csv 分隔符是逗号,因此请相应更改

$attendance = @'
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
'@ | ConvertFrom-Csv
$attendance | Add-Member -Name 'yesno' -MemberType ScriptProperty -Value {return  @('Yes', 'No')[$this.present -eq '0']}

$attendance | ft -a

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

答案 2 :(得分:1)

不幸的是,使用像 $attendance.present 这样的点符号会创建一个新数组,该数组不能用于操作 PSCustomObject 的原始数组。

我能想到的最短时间:

$attendance.foreach({ $_.present = ('No', 'Yes')[ $_.present ] })

无论 present 是整数还是字符串,这都有效。当用于索引数组时,PowerShell 会自动将字符串转换为整数。

稍长,使用 ternary operator(需要 PS7+):

$attendance.foreach({ $_.present = $_.present -eq 0 ? 'No' : 'Yes' })

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

答案 3 :(得分:-1)

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

相关问题