@jfbueno/

linq2-groupby-1

C#

https://medium.com/@buenojeferson/e566f929846b

fork
loading
Files
  • main.cs
  • main.exe
main.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
using System;
using System.Linq;
using System.Collections.Generic;
using System.Globalization;
using static System.Console;

/* 
* Código referente ao post 'Entendendo LINQ 2: Como usar o método GroupBy' => https://medium.com/@buenojeferson/e566f929846b
*/

class MainClass 
{
    private static readonly DateTimeFormatInfo _dtFormat = new CultureInfo("pt-BR").DateTimeFormat;

    static void Main(string[] args)
    {
        ComprasPorData();
        WriteLine($"\n{new string('=', 30)}\n");
        ComprasPorCliente();
    }

    static void ComprasPorCliente()
    {
        IEnumerable<IGrouping<string, Compra>> grupos = Compras.GroupBy(x => x.Cliente);

        foreach(var grupo in grupos)
        {
            WriteLine($"Compras de {grupo.Key}");
            foreach(var compra in grupo)
            {
                WriteLine($"\t {compra.Valor:n2}");
            }
        }

        // Agregações

        var agg = grupos.Select(gp => new 
        {
            Cliente = gp.Key,
            QuantidadeCompras = gp.Count(),
            MelhorCompra = gp.Max(x => x.Valor),
            PiorCompra = gp.Min(x => x.Valor),
            TotalCompras = gp.Sum(x => x.Valor)
        });

        WriteLine();
        foreach(var elemento in agg) 
        {
            WriteLine($"Cliente: {elemento.Cliente}");
            WriteLine($"Quantidade de compras: {elemento.QuantidadeCompras}");
            WriteLine($"Melhor Compra: {elemento.MelhorCompra}");
            WriteLine($"Pior Compra: {elemento.PiorCompra}");
            WriteLine($"Total em compras: {elemento.TotalCompras}");
            WriteLine();
        }

        // Apenas clientes com mais de uma compra
        var aggComFiltro = grupos.Where(gp => gp.Count() > 1).Select(gp => new 
        {
            Cliente = gp.Key,
            PiorCompra = gp.Where(c => c.Valor > 150).Min(x => x.Valor)
            // Apenas compras acima de 150
        });

        WriteLine();
        foreach(var elemento in aggComFiltro) 
        {
            WriteLine($"Cliente: {elemento.Cliente}");
            WriteLine($"Pior compra (acima de 150): {elemento.PiorCompra}");
            WriteLine();
        }
    }

    static void ComprasPorData()
    {
        IEnumerable<IGrouping<int, Compra>> grupos = Compras.GroupBy(compra => compra.Data.Month);

        foreach(var grupo in grupos)
        {
            WriteLine($"Compras pagas no mês de {_dtFormat.GetMonthName(grupo.Key)}");
            foreach(var elemento in grupo) 
            {
                WriteLine($"\t{elemento.ToString()}");
            }
            WriteLine();
        }

        // Agrupamento aninhado
        var comprasPorMesECliente = Compras.GroupBy(compra => compra.Data.Month).Select(gp => new 
        {
            Mes = _dtFormat.GetMonthName(gp.Key),
            TotalComprasMes = gp.Sum(c => c.Valor),
            MaiorCompraMes = gp.Max(c => c.Valor),
            QtdComprasMes = gp.Count(),

            ComprasPorCliente = gp.GroupBy(c => c.Cliente).Select(g => new 
            {
                Cliente = g.Key,
                Compras = g.ToArray(),
                Total = g.Sum(c => c.Valor),
                MaiorValor = g.Max(c => c.Valor),
                Qtd = g.Count()
            })
        });

        WriteLine();
        foreach(var grupo in comprasPorMesECliente)
        {
            WriteLine($"Mês: {grupo.Mes}");
            WriteLine($"{grupo.QtdComprasMes} compras, com um total de {grupo.TotalComprasMes}.");
            WriteLine($"A maior compra foi de {grupo.MaiorCompraMes:n2}");

            foreach(var grupoInterno in grupo.ComprasPorCliente) 
            {
                WriteLine($"\t{grupoInterno.Cliente} fez {grupoInterno.Qtd} compras, com um total de {grupoInterno.Total}");
                WriteLine($"\tA maior compra foi de {grupoInterno.MaiorValor:n2}");
                foreach(var elemento in grupoInterno.Compras)
                {
                    WriteLine($"\t\t{elemento.Valor:n2} em {elemento.Data:dd/MM}");
                }                
                WriteLine();
            }            
            WriteLine();
        }
    }

    static IReadOnlyCollection<Compra> Compras => new []
    {
        new Compra { Valor =  100, Data = new DateTime(2019, 01, 19), Cliente = "Finn" },
        new Compra { Valor =  200, Data = new DateTime(2019, 02, 05), Cliente = "Jake" },
        new Compra { Valor = 1350, Data = new DateTime(2019, 02, 07), Cliente = "BMO" },
        new Compra { Valor =  900, Data = new DateTime(2019, 01, 21), Cliente = "Finn" },
        new Compra { Valor =  150, Data = new DateTime(2019, 02, 05), Cliente = "Jake" },
        new Compra { Valor = 1500, Data = new DateTime(2019, 02, 09), Cliente = "Finn" },
        new Compra { Valor =  300, Data = new DateTime(2019, 03, 10), Cliente = "Marceline" },
        new Compra { Valor = 1200, Data = new DateTime(2019, 03, 15), Cliente = "Marceline" },
        new Compra { Valor = 1900, Data = new DateTime(2019, 01, 10), Cliente = "Marceline" },
        new Compra { Valor = 2500, Data = new DateTime(2019, 03, 18), Cliente = "Finn" }
    };
}

public class Compra
{
    public string Cliente { get; set; }
    public decimal Valor { get; set; }
    public DateTime Data { get; set; }

    public override string ToString() => $"{Cliente}, com valor de {Valor:n2} em {Data:dd/MM}";
}