I was not sure on the precise term but what I tried to do using LINQ was "switching" the keys of a dictionary with the keys of its child.
This is the collection I have got as input:
Key:HeaderID Value:
Key:ItemID Value:Object
Key:ItemID Value:Object
Key:ItemID Value:Object
Key:HeaderID Value:
Key:ItemID Value:Object
Key:ItemID Value:Object
Key:ItemID Value:Object
Key:HeaderID Value:
Key:ItemID Value:Object
Key:ItemID Value:Object
Key:ItemID Value:Object
And this is the collection I want as output:
Key:ItemID Value:
Key:HeaderID Value:Object
Key:HeaderID Value:Object
Key:HeaderID Value:Object
Key:ItemID
Key:HeaderID Value:Object
Key:HeaderID Value:Object
Key:HeaderID Value:Object
Key:ItemID
Key:HeaderID Value:Object
Key:HeaderID Value:Object
Key:HeaderID Value:Object
I have already created the code in VB.net:
Dim objInput As Dictionary(Of String, Dictionary(Of String, Object)) = fakefunction()
' ItemID -> HeaderID ColumnValue
Dim objOutput As New Dictionary(Of String, Dictionary(Of String, Object))
For Each strHeaderID As String In objInput.Keys
Dim objColumnValuesPerItem As Dictionary(Of String, Object) = objInput(strHeaderID)
For Each strItemID As String In objColumnValuesPerItem.Keys
Dim objColumnValue As Object = objColumnValuesPerItem(strItemID)
If Not objOutput.ContainsKey(strItemID) Then
objOutput.Add(strItemID, New Dictionary(Of String, Object))
End If
objOutput(strItemID).Add(strHeaderID, objColumnValue)
Next
Next
The reason I ask this question is pure educational, I have tried to use LINQ to get convert this to the correct list, only I wasn't getting anywhere without creating very complex and long LINQ statements.
I don't know any VB.Net but I think this should do what you want.
Dim objOutput As Dictionary(Of String, Dictionary(Of String, Object)) =
objInput _
.SelectMany(Function(oKvp) oKvp.Value.Select(Function(iKvp) New With { _
.OuterKey = oKvp.Key, _
.InnerKey = iKvp.Key, _
.Value = iKvp.Value})) _
.GroupBy(Function(tri) tri.InnerKey) _
.ToDictionary( _
Function(g) g.Key, _
Function(g) g.ToDictionary( _
Function(tri) tri.OuterKey, _
Function(tri) tri.Value))
Basically, you flatten your whole nested dinctionary into a sequence of objects with both keys and the value, then group them by the inner key, and then convert back into nested dictionaries.