Lambda GroupBy by year and month

11

I have a list of events, and I would like to group them by year and month, for example

[Year 2017]
Month January
 {Event 1, Event 2, Event 2}

Month February
 {Event 3}

[Year 2018]
Month January
 {Event 4, Event 5}

I'm using Lambda in C #, I have something like this already:

var groupLista = listaDeEventos.GroupBy(x => new {x.Data.Year, x.Data.Month})....
    
asked by anonymous 11.01.2017 / 20:43

2 answers

13

Basically, there are two ways to do this.

The complicated way, where it is necessary to make a grouping by year and another month, this second one being within the first ok, nor even so complicated ).

And also the easy way, which would be to group directly by month and by year, together, that is, concatenate year month in a way that they are unique keys to the grouping.

If you need to maintain a hierarchy (event -> month -> year), use the complicated form. Otherwise, I do not see why not use the simplest form.

The code at the end of the post has an example of each of the two forms.

It is also possible to make a "double" grouping, as you showed in the question, just to illustrate, it would look like this:

var grupo= listaEventos.GroupBy(x => new { x.Data.Year, x.Data.Month }) 
                       .Select(g => new { Key = g.Key, Itens = g.ToList() });

foreach(var i in grupo1)
{
    WriteLine($"{i.Key.Year} - { i.Key.Month }");

    foreach(var item in i.Itens)
    {
        WriteLine($"\t{item.Nome}");
    }

    WriteLine("\n");
}
using System;
using System.Linq;
using System.Collections.Generic;
using static System.Console;

public class Program
{
    internal static void MetodoFacil()
    {
        var grupo1 = listaEventos.GroupBy(c => c.Data.ToString("MM/yyyy"))
                                  .Select(g => new { Key = g.Key, Itens = g.ToList() });

        foreach(var i in grupo1)
        {
            WriteLine(i.Key);

            foreach(var item in i.Itens)
            {
                WriteLine($"\t{item.Nome}");
            }

            WriteLine("\n");
        }
    }

    internal static void MetodoComplicado()
    {
        var grupo2 = listaEventos.GroupBy(c => c.Data.Year)
                                 .Select(g => new 
                                 { 
                                     Ano = g.Key, 
                                     Meses = g.ToList()
                                              .GroupBy(c => c.Data.ToString("MMMM"))
                                              .Select(grp => new 
                                                             { 
                                                                 Mes = grp.Key, 
                                                                 Eventos = grp.ToList() 
                                                             })
                                 });

        foreach(var i in grupo2)
        {
            WriteLine($"Ano: {i.Ano}");

            foreach(var mes in i.Meses)
            {
                WriteLine($"\tMês: {mes.Mes}");

                foreach(var evento in mes.Eventos)
                {
                    WriteLine($"\t\t{evento.Nome}");
                }

                WriteLine("\n");
            }           
        }
    }

    public static void Main()
    {           
        MetodoFacil();      
        MetodoComplicado();
    }

    internal static List<Evento> listaEventos = new List<Evento>
    {
        new Evento { Nome = "Evento 1", Data = new DateTime(2015, 01, 01) },
        new Evento { Nome = "Evento 2", Data = new DateTime(2016, 01, 01) },
        new Evento { Nome = "Evento 3", Data = new DateTime(2016, 01, 22) },
        new Evento { Nome = "Evento 4", Data = new DateTime(2016, 02, 24) },
        new Evento { Nome = "Evento 5", Data = new DateTime(2016, 03, 30) },
        new Evento { Nome = "Evento 6", Data = new DateTime(2016, 04, 04) },
        new Evento { Nome = "Evento 7", Data = new DateTime(2017, 01, 01) },
        new Evento { Nome = "Evento 8", Data = new DateTime(2017, 09, 30) },
        new Evento { Nome = "Evento 9", Data = new DateTime(2018, 05, 12) },
    };
}

public class Evento
{
    public string Nome { get; set; }
    public DateTime Data { get; set; }  
}

See working on .NET Fiddle | Code in GitHub for future reference

    
11.01.2017 / 21:19
7

Everything will depend on how and where you will use, issuing in a console application as a way of counting the

11.01.2017 / 21:19