【问题标题】:How to group and merge list of data using LINQ?如何使用 LINQ 对数据列表进行分组和合并?
【发布时间】:2011-04-19 14:36:28
【问题描述】:

我有一个如下所示的数据列表

原始数据

Genre   Name                       Year 
Comedy  Shrek Forever After        2010
Drama   The Karate Kid             2010
Action  Iron Man 2                 2010
Action  Robin Hood                 2010
Drama   The Kids Are All Right     2010
Sci-Fi  Inception                  2010

我需要按类型对电影进行分组,并将相似的电影名称用“,”分隔,所以新列表看起来像

所需数据

 Genre   Name                                     Year 
 Comedy  Shrek Forever After                      2010
 Drama   The Karate Kid, The Kids Are All Right   2010
 Action  Iron Man 2, Robin Hood                   2010
 Sci-Fi  Inception                                2010

我写的LINQ语句如下

Dim result = From p In movies Group p By p.Genre Into Group Select New Movie With {
         .Genre = Genre,
         .Name = String.Join(", ", Group.Select(Function(p) p.Name).ToArray()),
         .Year = Group.Select(Function(p) p.Year).FirstOrDefault
        }

是否有其他方法可以让我不必使用“.Year = Group.Select(Function(p) p.Year).FirstOrDefault”或与我的方法不同的方法。强>

谢谢

示例代码:


Module Module1

    Sub Main()
        Dim movies As New List(Of Movie)
        movies.Add(New Movie("Comedy", "Shrek Forever After", 2010))
        movies.Add(New Movie("Drama", "The Karate Kid", 2010))
        movies.Add(New Movie("Action", "Iron Man 2", 2010))
        movies.Add(New Movie("Action", "Robin Hood", 2010))
        movies.Add(New Movie("Drama", "The Kids Are All Right", 2010))
        movies.Add(New Movie("Sci-Fi", "Inception", 2010))

        'Group amd Merge by genre
        Dim result = From p In movies Group p By p.Genre Into Group Select New Movie With {
         .Genre = Genre,
         .Name = String.Join(", ", Group.Select(Function(p) p.Name).ToArray()),
         .Year = Group.Select(Function(p) p.Year).FirstOrDefault
        }

        For Each r In result
            Console.WriteLine(r)
        Next
        Console.ReadKey()
    End Sub

    Public Class Movie
        Public Genre As String
        Public Name As String
        Public Year As Integer

        Public Sub New()
        End Sub

        Public Sub New(ByVal genre As String, ByVal name As String, ByVal year As Integer)
            Me.Year = year
            Me.Genre = genre
            Me.Name = name
        End Sub

        Public Overrides Function ToString() As String
            Return String.Format("Genre: {0}; Name:{1}; Year:{2}", Genre, Name, Year)
        End Function
    End Class

End Module

【问题讨论】:

    标签: vb.net linq list


    【解决方案1】:

    如果您确定 Year 永远不会为空,根据您的班级,它不应该是,您可以将其替换为:

    .Year = Group.First().Year
    

    但是,我质疑您的分组方法。当同一类型的电影不同年份时会发生什么?一个可能是 2009 年,另一个是 2010 年,你会自动选择第一年。您可以添加OrderBy 来获取最近的年份,但这完全取决于您的分组意图。

    【讨论】:

    • 感谢您的回复,我使用的示例只是为了获得一个想法,并且我假设年份每次都相同,因此您的建议对我有用。上述 LINQ 查询是否针对解决此类问题进行了优化。有什么替代建议吗?
    • @madan 我认为你所拥有的非常适合你的场景。如果它根据需要对所有内容进行分组,那么我认为无需更改它并且您的查询很简单。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    • 2013-09-05
    相关资源
    最近更新 更多