powershell数组添加成员-寻找优雅的代码

时间:2018-11-12 20:42:59

标签: 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

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

$Time2 = [math]::Round($TestArray.TimeStamp)

我正在考虑的代码是:

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

当然,我可以进行ForEach循环;它会很容易地处理它,但是我想在此单行代码中实现它。

有什么想法吗?

干杯, 菲利普

3 个答案:

答案 0 :(得分:5)

Mathias R. Jessen's answer通过创建 script 属性(类型ScriptProperty)来直接解决您的问题,该属性动态从封闭对象的{ {1}}属性。

  • 这种方法的优势在于,即使以后对.TimeStamp所做的更改也可以正确反映在.TimeStamp中,尽管这样做的代价是必须计算每次访问的值。

Manuel Batsching's答案提供了一种基于.Time2的替代方法,它可以像您最初尝试的那样创建静态音符属性(类型为Select-Object)。

  • 这种方法的优点是您只产生一次计算成本,但是以后对NoteProperty所做的更改不会反映在.TimeStamp中。

要提供更快的PSv5 +替代方案(每个方法调用一个,为了提高可读性而跨多个行):

.Time2
 
# ScriptProperty - dynamic
$TestArray.ForEach({ 
  $_.psobject.properties.Add(
    [psscriptproperty]::new('Time2', { [math]::Round($this.TimeStamp) })
  ) 
})

上述解决方案使用PSv4 + # NoteProperty - static $TestArray.ForEach({ $_.psobject.properties.Add( [psnoteproperty]::new('Time2', [math]::Round($_.TimeStamp)) ) }) 集合方法和PSv5 +静态.ForEach()类型方法来调用构造函数。


最后,一口气

以下基于::new()循环的笔记属性解决方案也可以解决您的问题,并且可以更快地完成;尽管为了便于阅读,它分散在多行中,但它也可以作为一种代码使用:

foreach

通常,尽管管道通常启用更优雅的单命令解决方案,但不幸的是,这是以牺牲性能为代价的。

答案 1 :(得分:2)

或者,您也可以使用Select-Object和自定义属性来实现相同目的:

$TestArray | Select-Object *,@{ n='Time2';e={ [math]::Round($_.TimeStamp) }}

答案 2 :(得分:1)

将成员类型更改为ScriptProperty,并将单个数组项称为$this

$TestArray |Add-Member Time2 -Value { [math]::Round($this.Timestamp) } -MemberType ScriptProperty

值得注意的是,在此示例中,管道本身充当foreach循环,展开数组并将每个单独的项绑定到Add-Member