// ========================================================================
//
// Copyright (C) 2016-2017 MARC CHEVALDONNE
//                         marc.chevaldonne.free.fr
//
// Module        : Program.cs
// Author        : Marc Chevaldonné
// Creation date : 2016-10-04
//
// ========================================================================

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using static System.Console;

namespace ex_031_011_LINQ_grouping
{
    class Program
    {
        static void Main(string[] args)
        {
            OutputEncoding = Encoding.UTF8;

            List<Nounours> nounours = new List<Nounours> {
                                      new Nounours("mouton", new DateTime(2009, 09, 16), 1000),
                                      new Nounours("ours", new DateTime(2009, 08, 15), 2000),
                                      new Nounours("chat", new DateTime(2009, 07, 14), 1000),
                                      new Nounours("chien", new DateTime(2009, 06, 13), 500),
                                      new Nounours("lapin", new DateTime(2009, 05, 12), 500),
                                      new Nounours("chat", new DateTime(2009, 07, 14), 2000),
                                      new Nounours("macaque", new DateTime(2009, 04, 11), 500)};
            ////////////
            //Grouping//
            ////////////

            //GroupBy : groupe les éléments en fonction d'un critère
            WriteLine("GroupBy avec un keySelector");
            IEnumerable<IGrouping<char, Nounours>> query
                = nounours.GroupBy(n => n.Nom[0]).OrderBy(group => group.Key);
            foreach (IGrouping<char, Nounours> group in query)
            {
                WriteLine($"nounours commençant par la lettre {group.Key} :");
                foreach (Nounours n in group)
                {
                    WriteLine($"\t{n}");
                }
            }
            WriteLine();

            //GroupBy avec Query Syntax
            WriteLine("GroupBy avec un keySelector");
            IEnumerable<IGrouping<char, Nounours>> queryQS = from n in nounours
                                                             group n by n.Nom[0] into grouping
                                                             orderby grouping.Key
                                                             select grouping;
            foreach (IGrouping<char, Nounours> group in queryQS)
            {
                WriteLine($"nounours commençant par la lettre {group.Key} :");
                foreach (Nounours n in group)
                {
                    WriteLine($"\t{n}");
                }
            }
            WriteLine();

            //GroupBy : avec keySelector et elementSelector
            WriteLine("GroupBy avec keySelector et elementSelector");
            IEnumerable<IGrouping<int, string>> query2
                = nounours.GroupBy(n => n.NbPoils, n => n.Nom).OrderBy(group => group.Key);
            foreach (IGrouping<int, string> group in query2)
            {
                WriteLine($"nounours de {group.Key} poils :");
                foreach (string s in group)
                {
                    WriteLine($"\t{s}");
                }
            }
            WriteLine();

            //GroupBy : avec keySelector et elementSelector avec Query Syntax
            WriteLine("GroupBy avec keySelector et elementSelector");
            IEnumerable<IGrouping<int, string>> query2QS = from n in nounours
                                                           group n.Nom by n.NbPoils into grouping
                                                           orderby grouping.Key
                                                           select grouping;
            foreach (IGrouping<int, string> group in query2QS)
            {
                WriteLine($"nounours de {group.Key} poils :");
                foreach (string s in group)
                {
                    WriteLine($"\t{s}");
                }
            }
            WriteLine();
        }
    }
}
