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

端模块

我将获取输出并将其转换为 observablecollection(of TagModel) - 所以我试图消除对数据的双重/三重处理。

谢谢

格雷姆

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 类似,不同之处在于,当应用于集合属性时,所有集合属性的内容都被展平并作为适当类型的单个集合返回,而不是作为集合集合返回。在这种情况下,它会从所有产品中获取所有标签,并将它们放入一个集合中以供使用。

Group By 则相反,它采用一个大的扁平组,并将其转换为集合的集合,根据指定的标准(在本例中为 t.Name)进行分组。

于 2011-04-03T07:26:08.717 回答