I needed to join dictionaries from within a list together, so that they become one whole dictionary.
First I thought it may be a trivial task. Than I used google and realized,
that everything on the first page was just wrong or impracticable for lists with unknown size.
What I found by googling, was stuff like:
$a = @{"foo"=1}
$b = @{"bar"=2}
$c = @($a,$b) | ForEach-Object {$_}
$a = @{"foo"=1}
$b = @{"bar"=2}
$c = $a + $b
Name Value
---- -----
foo 1
bar 2
E.g.
$c['foo']
Will output $null for the first example and "2" for the 2nd. But why is this?
Lets convert it to json (without piping, this is important) to visualize the data structure:
ConvertTo-Json -InputObject $c
which outputs for the first case:
[
{
"foo": 1
},
{
"bar": 2
}
]
and for the 2nd what we originally expected:
{
"bar": 2,
"foo": 1
}
So now we know that the first one did not join the dictionaries, but warped them into a list. As we originally looked for a solution to join a list of dictionaries, this is not helpful. (Note: From now on $c is the output from the first example, as it is the same as my original input). The 2nd one however looks helpful, but has two issues:
- It only works if we know how many elements we have (hard coded element count)
- It copies the list once for each element we want to add to it.
So let's address these issues:
- For the 1st one something like this will do the trick:
$c | ForEach-Object -Begin {[Hashtable]$aa = @{}} -Process {$aa += $_} -End {$aa} | ConvertTo-Json
- But for the 2nd we need something a bit more advanced like
$c | ForEach-Object -Begin {[Hashtable]$aa = @{}} -Process {foreach($element in ($_.GetEnumerator())) {$aa.Add($element.Key,$element.Value)}} -End {$aa} | ConvertTo-Json