使用两个等长数组执行数学运算
Perform math operations with two equal length arrays
我做的事情太简单了,以至于我都在努力寻找答案。我正在尝试从另一个中减去两个等长数组
$free_array = get-wmiobject -class win32_logicaldisk | select -ExpandProperty freespace
$size_array = get-wmiobject -class win32_logicaldisk | select -ExpandProperty size
ForEach ($size in $size_array)
{
Write-Host Statistic: $size - $freespace
}
我认为 PowerShell 没有同时映射多个数组的内置函数,因此您可以使用 range operator 然后根据需要对两个数组进行索引:
foreach ($Index in (0..($free_array.Count - 1))) {
Write-Host Statistic: ($size_array[$Index] - $free_array[$Index])
}
但是,您的任务也可以这样完成,我认为这样会更具可读性:
$LogicalDisks = Get-CimInstance -ClassName Win32_LogicalDisk
foreach ($LogicalDisk in $LogicalDisks) {
Write-Host Statistic: ($LogicalDisk.Size - $LogicalDisk.FreeSpace)
}
补充:
顺便说一句:下面我使用的是Get-CimInstance
rather than Get-WmiObject
, because the CIM cmdlets (e.g., Get-CimInstance
) superseded the WMI cmdlets (e.g., Get-WmiObject
) in PowerShell v3 (released in September 2012). Therefore, the WMI cmdlets should be avoided, not least because PowerShell (Core) 7+, where all future effort will go, doesn't even have them anymore. For more information, see this answer.
如果您可以对 单个 集合进行操作,您甚至不需要 foreach
循环并且可以使用单个管道调用 ForEach-Object
:
Get-CimInstance win32_logicaldisk | ForEach-Object {
"Statistic: " + ($_.Size - $_.FreeSpace)
}
至于并行枚举多个集合(不使用索引):
[Linq.Enumerable]::Zip()
可以为 两个 集合做到这一点:
# Two sample arrays to enumerate in parallel:
[string[]] $a1 = 'one', 'two', 'three'
[int[]] $a2 = 1, 2, 3
foreach ($tuple in [Linq.Enumerable]::Zip($a1, $a2)) {
'{0}: {1}' -f $tuple[0], $tuple[1]
}
注意:在早期的 PowerShell (Core) 版本和 Windows PowerShell 中,您必须使用 .Item1
/ .Item2
而不是 [0]
/ [1]
但是,如上所示,这是一个有点晦涩的解决方案,不是 PowerShell 惯用的,因为 PowerShell 不支持 .NET 扩展方法 并要求输入集合的强类型化以使 PowerShell 能够推断泛型方法应使用的特定类型。
此外,对于大小不同的输入集合,一旦较小的集合有运行项[=],枚举就会停止70=].
GitHub proposal #14732 建议引入 PowerShell 惯用的 功能,该功能不仅支持 2 集合:
- 更新:提案已被拒绝。
# Two sample arrays to enumerate in parallel:
$a1 = 'one', 'two', 'three'
$a2 = 1, 2, 3
# WISHFUL THINKING, as of PowerShell 7.2
foreach ($a1Element, $a2Element in $a1, $a2) {
'{0}: {1}' -f $a1Element, $a2Element
}
如果实现了这个特性,上面会输出:
one: 1
two: 2
three: 3
我做的事情太简单了,以至于我都在努力寻找答案。我正在尝试从另一个中减去两个等长数组
$free_array = get-wmiobject -class win32_logicaldisk | select -ExpandProperty freespace
$size_array = get-wmiobject -class win32_logicaldisk | select -ExpandProperty size
ForEach ($size in $size_array)
{
Write-Host Statistic: $size - $freespace
}
我认为 PowerShell 没有同时映射多个数组的内置函数,因此您可以使用 range operator 然后根据需要对两个数组进行索引:
foreach ($Index in (0..($free_array.Count - 1))) {
Write-Host Statistic: ($size_array[$Index] - $free_array[$Index])
}
但是,您的任务也可以这样完成,我认为这样会更具可读性:
$LogicalDisks = Get-CimInstance -ClassName Win32_LogicalDisk
foreach ($LogicalDisk in $LogicalDisks) {
Write-Host Statistic: ($LogicalDisk.Size - $LogicalDisk.FreeSpace)
}
补充
顺便说一句:下面我使用的是Get-CimInstance
rather than Get-WmiObject
, because the CIM cmdlets (e.g., Get-CimInstance
) superseded the WMI cmdlets (e.g., Get-WmiObject
) in PowerShell v3 (released in September 2012). Therefore, the WMI cmdlets should be avoided, not least because PowerShell (Core) 7+, where all future effort will go, doesn't even have them anymore. For more information, see this answer.
如果您可以对 单个 集合进行操作,您甚至不需要 foreach
循环并且可以使用单个管道调用 ForEach-Object
:
Get-CimInstance win32_logicaldisk | ForEach-Object {
"Statistic: " + ($_.Size - $_.FreeSpace)
}
至于并行枚举多个集合(不使用索引):
[Linq.Enumerable]::Zip()
可以为 两个 集合做到这一点:
# Two sample arrays to enumerate in parallel:
[string[]] $a1 = 'one', 'two', 'three'
[int[]] $a2 = 1, 2, 3
foreach ($tuple in [Linq.Enumerable]::Zip($a1, $a2)) {
'{0}: {1}' -f $tuple[0], $tuple[1]
}
注意:在早期的 PowerShell (Core) 版本和 Windows PowerShell 中,您必须使用 .Item1
/ .Item2
而不是 [0]
/ [1]
但是,如上所示,这是一个有点晦涩的解决方案,不是 PowerShell 惯用的,因为 PowerShell 不支持 .NET 扩展方法 并要求输入集合的强类型化以使 PowerShell 能够推断泛型方法应使用的特定类型。
此外,对于大小不同的输入集合,一旦较小的集合有运行项[=],枚举就会停止70=].
GitHub proposal #14732 建议引入 PowerShell 惯用的 功能,该功能不仅支持 2 集合:
- 更新:提案已被拒绝。
# Two sample arrays to enumerate in parallel:
$a1 = 'one', 'two', 'three'
$a2 = 1, 2, 3
# WISHFUL THINKING, as of PowerShell 7.2
foreach ($a1Element, $a2Element in $a1, $a2) {
'{0}: {1}' -f $a1Element, $a2Element
}
如果实现了这个特性,上面会输出:
one: 1
two: 2
three: 3