문제

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.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top