Powershell:将一个元素从一个数组添加到另一个数组

Powershell: adding an element from an array to another array

我正在尝试将元素添加到数组以进行过滤。在它第一次通过循环之后 我收到“方法调用失败,因为 [System.Management.Automation.PSObject] 不包含名为 'op_Addition' 的方法。”

我尝试了几种方法来解决这个问题。

$JsonDB = Get-Content 'Q:\TechnologyAA\HardwareCollection.json' | Out-String | ConvertFrom-Json
    foreach($client in $JsonDB)
        {
            if($client.HRSeparation -eq "No")
                {
                    $ClientNotHRSeparated += $client
                }
            else
                {
                    $ClientHRSeparated += $client
                }
        }
$JsonDB

任何帮助将不胜感激,谢谢!!

+= 的行为完全取决于左侧操作数。第一次赋值时,$ClientNotHRSeparated的值为$null,所以运算结果为:

$ClientNotHRSeparated = $null + $someCustomPSObject

PowerShell 评估为:

$ClientNotHRSeparated = $someObject

在第二次赋值时,$ClientNotHRSeparated 不再是 $null,PowerShell 会尝试识别 + 的重载,它适用于 [=20= 类型的两个操作数], 这就是它失败的地方。

如果要+=执行数组加法,提前定义两个数组变量,赋值一个可调整大小的数组(使用@()数组子表达式运算符):

$ClientNotHRSeparated = @()
$ClientHRSeparated = @()

$JsonDB = Get-Content 'Q:\TechnologyAA\HardwareCollection.json' | Out-String | ConvertFrom-Json
foreach ($client in $JsonDB) {
    if ($client.HRSeparation -eq "No") {
        $ClientNotHRSeparated += $client
    }
    else {
        $ClientHRSeparated += $client
    }
}
$JsonDB

现在 += 在第一次和之后都是明确的 - 无论哪种情况,左侧操作数都是一个数组。


作为手动遍历整个集合的替代方法,请考虑在 Split 模式下使用 .Where() 扩展方法:

$JsonDB = Get-Content 'Q:\TechnologyAA\HardwareCollection.json' | Out-String | ConvertFrom-Json

$ClientNotHRSeparated, $ClientHRSeparated = @($JsonDB).Where({$_.HRSeparation -eq 'No'}, 'Split')

更快更简洁:-)

ConvertFrom-Json 将 JSON 字符串解析为 PSObject(s)。 由于您没有在任何地方定义 $ClientNotHRSeparated$ClientHRSeparated,而是立即开始向其添加 ($client) 对象,因此在第一次迭代中您的变量 $ClientNotHRSeparated 将成为该客户端对象。 下次您执行 += 时,您正试图将一个对象添加到另一个不起作用的对象。

在脚本顶部定义变量,最好是具有 .Add() 方法的 List 对象。

$ClientNotHRSeparated = [System.Collections.Generic.List[object]]::new()
$ClientHRSeparated = [System.Collections.Generic.List[object]]::new()

然后在你的循环中使用它作为

$ClientNotHRSeparated.Add($client)
# same for $ClientHRSeparated

P.S。使用列表比添加到简单数组 (@()) 更 faster/better,因为当您使用 += 将项目添加到数组(具有固定长度)时,整个数组需要在内存中重建,消耗内存和处理时间

虽然这可行,但您根本不需要循环。只要做:

$ClientNotHRSeparated = $JsonDB | Where-Object { $_.HRSeparation -eq "No" }
$ClientHRSeparated = $JsonDB | Where-Object { $_.HRSeparation -ne "No" }

第一行可以改写为$JsonDB = Get-Content -Path 'Q:\TechnologyAA\HardwareCollection.json' -Raw | ConvertFrom-Json.
开关 -Raw 使 cmdlet 将文件内容读取为一个多行字符串