【问题标题】:Linq Concating a list of tags with count from an inner collection of an outer collectionLinq将标签列表与外部集合的内部集合中的计数连接起来
【发布时间】:2011-04-03 06:39:23
【问题描述】:

我正在尝试编写一个单一的 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) - 所以我试图消除对数据的双重/三重处理。

谢谢

格雷姆

【问题讨论】:

    标签: linq list linq-to-objects observablecollection generic-collections


    【解决方案1】:

    我是 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)进行分组。

    【讨论】:

      猜你喜欢
      • 2017-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多