Thursday 1 June 2017

LINQ 09 Flatten

Now we looked at joining two collections on a common property, but we also have the option of "Flattening" to collections into one, basically it's the same thing as joining but instead of the join function we leverage select all.

using System;
using System.Linq;

namespace pc.linq08
    class Person
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int DepartmentId { get; set; }
        public Person(string FirstName, string LastName, int DepartmentId)
            this.FirstName = FirstName;
            this.LastName = LastName;
            this.DepartmentId = DepartmentId;

    class Department
        public int Id { get; set; }
        public string Name { get; set; }
        public Department(int Id, string Name)
            this.Id = Id;
            this.Name = Name;

    class Program
        static void Main(string[] args)
            var ppl = new Person[] { new Person("Pawel", "Chooch",1),
                new Person("Magda", "Tyvoniuk",2), new Person("Tomek","Chooch",3),
                new Person("Marin","Smartzic",2), new Person("Jake","Tyvoniuk",1)};
            var depts = new Department[] { new Department(1, "IT"),
                new Department(2,"Finance"), new Department(3,"Operatios")};

            var result1 = from p in ppl
                          from d in depts
                          where p.DepartmentId == d.Id
                          select new {
                              FullName = $"{p.FirstName} {p.LastName}",
                              Department = d.Name,
                              Display = new Func<string>(
                                  () => $"{p.FirstName} {p.LastName}: {d.Name}")

            Array.ForEach(result1.ToArray(), pd => Console.WriteLine(pd.Display()));

            var result2 = ppl.SelectMany(p =>
                depts.Where(d => d.Id == p.DepartmentId)
                    .Select(d => new { FullName= $"{p.FirstName} {p.LastName}",
                                       Department = d.Name,
                                       Display= new Func<string>(
                                           ()=> $"{p.FirstName} {p.LastName}: {d.Name}")}));

            Array.ForEach(result2.ToArray(), pd => Console.WriteLine(pd.Display()));

and that's it, when it comes to the expressive syntax we just use two from statements which is pretty easy to wrap your head around, the method based syntax is a bit more confusing, so confusing i'm not sure how to explain it without regurgitating the explanation of the SelectMany function...