🙌
[PowerShell]PSCustomObjectで同じ要素(項目数・項目名)か比較するFunction
こちらの記事では、多次元配列 と ジャグ配列(多段配列)の要素数を比較しました。
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>
まとめ
しっかりと検証できていませんが、おそらくこのコードで比較できると思います。
データ構造体のプロパティなど、より細かく比較したい場合はカスタマイズしてご利用ください!
参考文献
関連記事
Discussion