I have Googled and seen this: In PowerShell, what's the best way to join two tables into one?
However, how can I do the JOIN without having that? Because our PS does not come with it and I don’t think we have permission to install new commands and we are on 5.1 too. So it has to be something built-in.
Now the question:
I have two APIs that I call with Invoke-RestMethod and they send me a array of JSON response like so:
[
{ "FirstName" : "Hi",
"Code" : 123
},
{ "FirstName" : "Bye",
"Code" : 456
}
]
so let’s say we have $res1 and $res2 with some response like above in them and I want to do the JOIN on Code field.
How can I do this without using the Join-Object?
>Solution :
You can put your own simple Merge-Object command together like so:
function Merge-Object {
param(
[Parameter(Mandatory)]
[array]$Left,
[Parameter(Mandatory)]
[array]$Right,
[Parameter(Mandatory)]
[string]$On)
# create an index/correlation table from the right-hand collection
# we'll use this to look up values based on the left-hand items' key property later
$correlationTable = @{}
$Right |ForEach-Object {
$key = $_.$On
if ($null -ne $key) {
$correlationTable[$key] = $_
}
}
# iterate over the left-hand collection, try to correlate with right
$Left |Where-Object {$null -ne ($key = $_.$On) -and $correlationTable.ContainsKey($key)} |ForEach-Object {
# look up corresponding row in right-hand collection
$correlated = $correlationTable[$_.$On]
# extract property names from current object
$existingNames = @($_.psobject.Properties.Name)
# generate property selectors for non-overlapping property names on the right
$selectors = $correlated.psobject.Properties.Name |Where-Object {$_ -notin $existingNames} |ForEach-Object {
@{Name="$_"; Expression=[scriptblock]::Create("`$correlated.'$_'")}
}
# create new joined object
$_ |Select-Object -Property @($existingNames;$selectors)
}
}
Then use it like:
$res1 = @'
[
{
"FirstName": "Jane",
"Code": 123
},
{
"FirstName": "Robert",
"Code": 456
}
]
'@ |ConvertFrom-Json
$res2 = @'
[
{
"LastName": "Doe",
"Code": 123
},
{
"LastName": "Paulson",
"Code": 456
}
]
'@ |ConvertFrom-Json
Merge-Object -Left $res1 -Right $res2 -On Code |ConvertTo-Json
Which should give you:
[
{
"FirstName": "Jane",
"Code": 123,
"LastName": "Doe"
},
{
"FirstName": "Robert",
"Code": 456,
"LastName": "Paulson"
}
]