🙌

[PowerShell]PSCustomObjectで同じ要素(項目数・項目名)か比較するFunction

2025/03/03に公開

こちらの記事では、多次元配列 と ジャグ配列(多段配列)の要素数を比較しました。
PowerShellでは、そのほかにPSCustomObjectというデータ構造体を使用できます。

本記事では、「PSCustomObject」同士の要素(項目名、項目数)を比較する方法を紹介。

自作したコード

PSCustomObjectで要素を比較するコード
Function Test-IsPSCustomObject {
    param(
        [Parameter(Mandatory=$true)]
        [System.Object[]]$Argument
    )

    foreach ($arg in $Argument) {
        if (-not ($arg -is [System.Management.Automation.PSCustomObject])) {
            return $false
        }
    }
    return $true
}
Function Test-PSCustomObjectEquality {
    param (
        [Parameter(Mandatory=$true)][System.Object[]]$Object1,
        [Parameter(Mandatory=$true)][System.Object[]]$Object2
    )

    # データ存在チェック
    if (($Object1.Count -eq 0) -or ($Object2.Count -eq 0)) {
        Write-Warning "いずれか引数のデータがありません。[引数1の件数: $($Object1.Count), 引数2の件数: $($Object2.Count)]"
        return $false
    }

    # オブジェクト内がPSCustomObjectであるか判定
    if (-not (Test-IsPSCustomObject $Object1)) {
        Write-Warning '引数の「Object1」がPSCustomObjectではありません。'
        return $false
    }
    elseif (-not (Test-IsPSCustomObject $Object2)) {
        Write-Warning '引数の「Object2」がPSCustomObjectではありません。'
        return $false
    }

    # 項目名と項目数を比較
    $object1ColumnData = $Object1[0].psobject.properties | ForEach-Object { $_.Name }
    $object2ColumnData = $Object2[0].psobject.properties | ForEach-Object { $_.Name }
    $compareResult = (Compare-Object $object1ColumnData $object2ColumnData -SyncWindow 0)
    if (($null -ne $compareResult) -and ($compareResult.Count -ne 0)) {
        Write-Warning "オブジェクト同士の項目が一致していません。"
        return $false
    }

    # # データ件数を比較(チェックする場合は、コメントアウト解除)
    # if ($Object1.Count -ne $Object2.Count) {
    #     Write-Warning "オブジェクト内のデータ件数が一致しません。[引数1の件数: $($Object1.Count), 引数2の件数: $($Object2.Count)]"
    #     return $false
    # }

    # 比較した結果2つのオブジェクトが一致
    return $true
}

テストコード

# 4つのPSCustomObjectと1つのジャグ配列を作成
#   object1 と object2 は同一。
$object1 = @(
    [PSCustomObject]@{Name="Zennさん"; Age=25},
    [PSCustomObject]@{Name="Devさん"; Age=30}
)
$object2 = @(
    [PSCustomObject]@{Name="Zennさん"; Age=25},
    [PSCustomObject]@{Name="Devさん"; Age=30}
)
#   object1(またはobject2) と object3は要素数が同一
$object3 = @(
    [PSCustomObject]@{Name="Powerさん"; Age=22},
    [PSCustomObject]@{Name="Shellさん"; Age=40}
)
# object3 は要素数(項目数)が少ない
$object4 = @(
    [PSCustomObject]@{Name="Zennさん"}
)
# object4 は要素数(項目数)が多い
$object5 = @(
    [PSCustomObject]@{Name="Zennさん"; Age=25; City="Tokyo"},
    [PSCustomObject]@{Name="Devさん"; Age=30; City="Kyoto"}
)
# ジャグ配列
$array1 = @(
    @(1, 2, 3),
    @(4, 5)
)

# テストコード
# Function「Test-IsPSCustomObject」のテスト
Write-Host "Testing Test-IsPSCustomObject..."
# 正常系
if (Test-IsPSCustomObject -Argument $object1) {
	Write-Host "Object1 is a PSCustomObject array."
} else {
	Write-Host "Object1 is NOT a PSCustomObject array."
}
if (Test-IsPSCustomObject -Argument $object4) {
	Write-Host "Object4 is a PSCustomObject array."
} else {
	Write-Host "Object4 is NOT a PSCustomObject array."
}
# 異常系
if (Test-IsPSCustomObject -Argument $array1) {
	Write-Host "array1 is a PSCustomObject array."
} else {
	Write-Host "array1 is NOT a PSCustomObject array."
}

# Function「Test-PSCustomObjectEquality」のテスト
Write-Host "Testing Test-PSCustomObjectEquality..."
# 正常系
if (Test-PSCustomObjectEquality -Object1 $object1 -Object2 $object2) {
	Write-Host "Object1 and Object2 are equal."
} else {
	Write-Host "Object1 and Object2 are NOT equal."
}
if (Test-PSCustomObjectEquality -Object1 $object1 -Object2 $object3) {
	Write-Host "Object1 and Object3 are equal."
} else {
	Write-Host "Object1 and Object3 are NOT equal."
}
# 異常系
if (Test-PSCustomObjectEquality -Object1 $object1 -Object2 $object4) {
	Write-Host "Object1 and Object4 are equal."
} else {
	Write-Host "Object1 and Object4 are NOT equal."
}
if (Test-PSCustomObjectEquality -Object1 $object1 -Object2 $object5) {
	Write-Host "Object1 and Object5 are equal."
} else {
	Write-Host "Object1 and Object5 are NOT equal."
}

テストコードの実行結果

すべて期待通りの結果となりました。

実行結果
Testing Test-IsPSCustomObject...
Object1 is a PSCustomObject array.
Object4 is a PSCustomObject array.
array1 is NOT a PSCustomObject array.
Testing Test-PSCustomObjectEquality...
Object1 and Object2 are equal.
Object1 and Object3 are equal.
警告: オブジェクト同士の項目名が一致していません。
Object1 and Object4 are NOT equal.
警告: オブジェクト同士の項目名が一致していません。
Object1 and Object5 are NOT equal.
PS XXXX>

まとめ

しっかりと検証できていませんが、おそらくこのコードで比較できると思います。

データ構造体のプロパティなど、より細かく比較したい場合はカスタマイズしてご利用ください!

参考文献

https://zenn.dev/haretokidoki/articles/c1aeace31dbf48

関連記事

https://haretokidoki-blog.com/pasocon_powershell-startup/
https://zenn.dev/haretokidoki/articles/7e6924ff0cc960
https://zenn.dev/haretokidoki/articles/fb6830f9155de5

GitHubで編集を提案

Discussion