powershell数组add-member - 寻找优雅的代码

Phi*_*ppe 3 arrays powershell pipeline

我有一个非常基本的PowerShell数组:$ TestArray有2个文本列:Price和TimeStamp(这就是我得到它们的方式,没有什么可以做的):

Price  TimeStamp       
-----  ----------------       
0.0567 1542056680.72746
0.0567 1542056650.34414
0.0555 1542056197.46668
0.0551 1542056167.28967
Run Code Online (Sandbox Code Playgroud)

我想,在单个PowerShell行中添加一个舍入Time2

$Time2 = [math]::Round($TestArray.TimeStamp)
Run Code Online (Sandbox Code Playgroud)

我想的代码是:

 $TestArray | Add-Member -Name Time2 -MemberType NoteProperty -Value { [math]::Round($Table.TimeStamp) }
Run Code Online (Sandbox Code Playgroud)

当然,我可以做一个ForEach循环; 它可以很容易地处理它,但我想在这一行代码中实现这一点.

任何的想法 ?

干杯,菲利普

mkl*_*nt0 5

Mathias R. Jessen的答案通过创建一个脚本属性(类型ScriptProperty)直接解决了您的问题,该属性从封闭对象的属性中动态计算其值.TimeStamp.

  • 这种方法的优点是,即使以后的更改.TimeStamp也会正确地反映出来.Time2,尽管以每次访问的价值计算为代价.

曼努埃尔Batsching的答案提供了一个Select-Object创建基于替代静态附注属性(类型NoteProperty),因为你已经尝试原来自己.

  • 这种方法的优点是,您只需要计算一次计算成本,但以后的更改.TimeStamp将不会反映出来.Time2.

提供更快的PSv5 +替代方案(每个方法调用一次,分布在多行以便于阅读):

# ScriptProperty - dynamic
$TestArray.ForEach({ 
  $_.psobject.properties.Add(
    [psscriptproperty]::new('Time2', { [math]::Round($this.TimeStamp) })
  ) 
})
Run Code Online (Sandbox Code Playgroud)
# NoteProperty - static
$TestArray.ForEach({ 
  $_.psobject.properties.Add(
    [psnoteproperty]::new('Time2', [math]::Round($_.TimeStamp))
  ) 
})
Run Code Online (Sandbox Code Playgroud)

上述解决方案使用PSv4 + .ForEach()集合方法和PSv5 +静态::new()类型方法来调用构造函数.


最后,重新单线:

以下foreach基于循环的音符属性解决方案也可以解决您的问题,并且会更快 ; 虽然它在这里分布在多行以便于阅读,但它也可以作为一个单行使用:

foreach ($el in $TestArray) { 
  Add-Member -InputObject $el -Name Time2 -MemberType NoteProperty `
             -Value ([math]::Round($el.TimeStamp)) 
}
Run Code Online (Sandbox Code Playgroud)

通常,虽然管道通常能够实现更优雅的单命令解决方案,但不幸的是,这会以牺牲性能为代价.