使用两个等长数组执行数学运算

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