1

親製品の外側のコレクションからタグの内側のコレクションを連結し、カウントの降順で並べ替えられた統合カウントでタグのコレクションを返すことができる単一の Linq クエリを作成しようとしています。

これは私が現在持っていて、単一のLinqクエリに変換するための助けを探している実用的なソリューションです.

Module Module1

Class Tag
    Property Name As String
    Property Count As Integer
End Class

Class Product
    Property Name As String
    Property tags As List(Of Tag)
End Class

Sub Main()

    Dim Products As New List(Of Product) From {
            {New Product With {.Name = "P1",
                               .tags = New List(Of Tag) From {{New Tag With {.Name = "T1"}},
                                                              {New Tag With {.Name = "T3"}},
                                                              {New Tag With {.Name = "T5"}}
                                                             }
                              }
            },
            {New Product With {.Name = "P2",
                               .tags = New List(Of Tag) From {{New Tag With {.Name = "T2"}},
                                                              {New Tag With {.Name = "T4"}},
                                                              {New Tag With {.Name = "T6"}}
                                                             }
                              }
            },
            {New Product With {.Name = "P3",
                               .tags = New List(Of Tag) From {{New Tag With {.Name = "T2"}},
                                                              {New Tag With {.Name = "T3"}},
                                                              {New Tag With {.Name = "T4"}}
                                                             }
                              }
            },
            {New Product With {.Name = "P4",
                               .tags = New List(Of Tag) From {{New Tag With {.Name = "T4"}},
                                                              {New Tag With {.Name = "T5"}},
                                                              {New Tag With {.Name = "T6"}},
                                                              {New Tag With {.Name = "T7"}},
                                                              {New Tag With {.Name = "T8"}}
                                                             }
                              }
            }
        }


    Dim ReportingTags As New List(Of Tag)

    '-- Start : Needs to be converted to pure Linq (if possible)------------------------------------------

    Dim InterimTags As New List(Of String)

    For Each p As Product In Products
        Dim TmpTags As New List(Of String)
        InterimTags.AddRange(TmpTags.Concat(From t In p.tags Select t.Name))
    Next

    ReportingTags.AddRange((From t In InterimTags
                            Group By name = t Into Count = Count()
                            Select New Tag With {.Name = name,
                                                 .Count = Count}).OrderByDescending(Function(t) t.Count))

    '-- End ----------------------------------------------------------------------------------------------

    For Each t As Tag In ReportingTags
        Console.WriteLine("Tag: {0} - Count: {1}", t.Name, t.Count)
    Next

    Console.ReadLine()

End Sub

エンドモジュール

私は出力を取得し、(TagModel の) observablecollection に変換します。そのため、データの二重/三重処理を排除しようとしています。

ありがとう

グレアム

4

1 に答える 1

0

私は C# 派ですが、Linq は Linq なので、試してみようと思いました。あなたの赤い部分に以下を入れることで、あなたの結果を一致させることができました:

Dim outStuff = From t In Products.SelectMany(Function(p) p.tags)
               Group By tagName = t.Name
               Into g = Group, Count()
               Order By Count Descending

そして、私は使用しました

For Each t In outStuff
    Console.WriteLine("Tag: {0} - Count: {1}", t.tagName, t.Count)
Next

出力を行います。

これは最も優雅でエレガントな VB ではないことは確かです。おそらく、Linq をもう少しきれいに改良することができますが、それはあなたにとって良いスタートになるはずです。

あなたの質問のサンプル コードは、これを行うのに大いに役立ちました。

簡単に説明すると、SelectMany または Group By に慣れていない場合、これらはいくつかの異なる非常に便利なことを行います。

SelectMany は Select と同じように機能しますが、コレクション プロパティに適用すると、すべてのコレクション プロパティの内容がフラット化され、コレクションのコレクションとして返されるのではなく、適切な型の単一のコレクションとして返される点が異なります。この場合、すべての製品からすべてのタグを取得し、それらを 1 つのコレクションにまとめて操作します。

Group By は逆のことを行い、大きなフラット グループを取得して、指定された基準 (この場合は t.Name) に従ってグループ化されたコレクションのコレクションに変換します。

于 2011-04-03T07:26:08.717 に答える