C# LINQ cheatsheet with code examples.

// ---------------------------------------------------------------------------
// LINQ Extensions Cheat Sheet - LinqExtensionMethods.cs
//
// https://github.com/lukewickstead/DOT-NET-on-Linux/blob/master/CheatSheets/LinqExtensionMethods.cs
// ---------------------------------------------------------------------------

// **** AGGREGATE ****
data.Count()            // The count of items
data.Cout(x => x.Condition == true)     // Count items which pass criteria
data.Sum (x => x.Value);        // Sum of all items
data.Min(x => a.Value);         // Min value
data.Max(x => a.Value);         // Max value
data.Average(x => a.Value);       // Average
data.Select(x => new { A = x.Name, B = x.Min(x.Value))  // Nested Aggregate
data.GroupBy( x => x.Type)
  .Select( y =>
  new { Key = y.Key,
        Average = y.Average ( z => z.Value ) } ); // Grouped Aggregate


// **** CONVERSIONS ****
data.ToArray();           // Convert to Array
data.ToList();            // Convert to List
data.ToDictionary( x=> x.Name );      // Convert to Dictionary keyed on Name
data.OfType<decimal> ().ToList ()     // Filters out all elements not of provided type
data.Cast<decimal> ().ToList ()       // Cast can only cast to Implemented Interfaces and classes within the hierachy
data.ConvertAll<double> (x => Convert.ToDouble (x));  // Convert all items with provided conversion method


// **** ELEMENT ****
data.First()            // Returns the first element
data.First( x=> x.Type == Types.A )     // Returns the first element passing the condition
data.FirstOrDefault( )          // Returns the first element or default*
data.FirstOrDefault( x => x.Type == Types.B )   // Returns the first element passing the condition or default*
data.Last()           // Returns the last element
data.Last( x=> x.Type == Types.A )      // Returns the last element passing the condition
data.LastOrDefault( )         // Returns the last element or default*
data.LastOrDefault( x => x.Type == Types.B )    // Returns the last element passing the condition or default*
data.ElementAt(0)         // Returns the element at position 0
*default            // Default is defined as default(typeOf(T)) or new Constructor() without any constructor parameters


// **** FILTERS ****
data.Where(x => x.Type == Types.A)      // Returns all elements passing the condition
data.Where(( x, index) => index <= 4 && x.Type == Types.A) // The elements index can be passed into the delegate


// **** GENERATION ****
Enumerable.Range(1, 10);        // Creates collection of 10 items between 1 and 10
Enumerable.Repeat(1, 10);       // Creates a collection of 10 1s.


// **** GROUPING ****
// Grouping is not like SQL where columns have to be aggregates or wihtin the group list; you group the elements into a list for each group

data.GroupBy (x => x.Type)
    .Select (grp => new { Key = grp.Key, Value = grp.Count ()}); // Group with count of data

data.GroupBy (x => x.Type)
    .Select (grp => new { Key = grp.Key,  Value = grp.OrderBy (x => x.Name)}); // Create a collection of elements ordered by name for each group of Type


// **** ORDERING ****
data.OrderBy (x => x.Name);         // Order by Name ASC
data.OrderBy (x => x.Name).ThenBy (x => x.Age);     // Order by Name ASC the Age ASC
data.OrderBy (x => x.Name).ThenByDescending (x => x.Age); // Order by Name ASC then Age DESC
data.OrderByDescending (x => x.Name);       // Order by Name DESC
data.OrderBy (x => x.Name,          // Order by Name ASC Case insensative
  StringComparer.CurrentCultureIgnoreCase);
data.OrderBy (x => x.Name).Reverse ();        // Reverse elements


// **** PARTITIONING ****
data.Take (3);              // Take 3 items
data.Skip (3);              // Skip 3 items
data.TakeWhile (x=>x.Type ==Types.A);       // Take all the items while the condition is met
data.SkipWhile (x=>x.Type ==Types.A);       // Skip all the items while the condition is met


// **** PROJECTION ****
data.Select (x => x.Name);          // Select collection of a column
data.Select (x => new { Name = x.Name, Age = x.Age });    // Select a collection of columns through an anonymus type
data.SelectMany (x => x.Children)       // SelectMany flattens collections into one collection


// **** QUANTIFIERS ****
data.Any (x => x.Type == Types.TypeA);        // Returns True/False if any element meets the condition
data.All (x => x.Type == Types.TypeA);        // Returns True/False if all the elements meet the condition


// **** SET ****
data.Distinct ();           // Returns a collection of distinct elements
data.Intersect(dataTwo);          // Returns the union / intersection of data; elements in both collections
data.Except(dataTwo);           // Returns elements in data which are not in dataTwo
data.Concat(dataTwo);           // Concatonates both collections; appends dataTwo to data
data.SequenceEqual(dataTwo));         // Returns True if data has the same data and sequence of dataTwo
data.Join(dataTwo,            // Joins the data together like SQL join
    x => x.Type,            // Join field on data
    y => y.Type,            // Join field on dataTwo
    ( d1, d2 ) => new { Name = d1.Name, Type = d1.Type, Desc = d2.Descripion} ); // Selection criteria

data.Distinct (new AComparer ()).       // Distinct with providing an equality provider
public class AComparer : IEqualityComparer<A>
{
    public bool Equals (A x, A y) { return a == a;}
    public int GetHashCode (A obj) { return obj.GetHashCode(); }
}

// ---------------------------------------------------------------------------
// LINQ Cheat Sheet - Linq.cs
//
// https://github.com/lukewickstead/DOT-NET-on-Linux/blob/master/CheatSheets/Linq.cs
// ---------------------------------------------------------------------------

// **** AGGREGATE ****

// Aggregate Linq Ext methods can be applied to natural Linq
.Count()
.Min()
.Max()
.Average()
.Sum()


// Aggregate
var count = (from p in people
        select p).Count ();

// Conditional Aggregate
var count = (from p in people
             where p.Gender == Gender.Male
             select p).Count ();

// Nested Aggregate
var samplePeople = from p in people
           select new { Name= p.Name,
                ChildrenCount =
                  (from c in p.Children
                   where c.Gender == Gender.Female
                   select c).Count () };

// Grouped Aggregate
var children = from p in people
    group p by p.Gender into peopleGenders
        let minKids = peopleGenders.Min( x => x.Children.Count())
    select new { Gender = peopleGenders.Key, Value = peopleGenders.Count() };

// Let satement
var children = from p in people
    let x = peopleGenders.Count( x => x.Children.Count())
    select x

// **** CONVERSIONS ****
// All conversions functions should be done with Linq ext methods ToArray(), ToList(), ToDictionary(), OfType(), Cast(); see Linq Ext cheet sheet here.

// **** ELEMENT ****
// All element functions should be done with Linq ext methods First(), FirstOrDefault(), Last(), LastOrDefault(), ElementAt(); see Linq Ext cheet sheet here.

// **** FILTER ****
// Where filter
var count = (from p in people
             where p.Age < 30
             select p).Count ();

// Drilled where filter
var count = (from p in people
             where p.Children.Count () > 0
             select p).Count ();

// **** GENERATION ****
// All generation functions should be done with Linq ext methods Enumerable.Range() and Enumerable.Repeat(); see Linq Ext cheet sheet here

// **** GROUPING ****
// Group by gender and count...
var samplePeople = from p in people
    group p by p.Gender into gens
    select new { Key = gens.Key, Value = gens.Count()};

// Split into groups of gender by grouping on Name
var samplePeople = from p in people
    group p by p.Gender into gens
    select new { Key = gens.Key, Value = gens.OrderBy( x => x.Name)};


// **** ORDERING ****
// Order ASC
var orderdPeople = from p in people
    orderby p.Name
    select new { p.Name, p.Age, p.Children, p.Gender };

// Order DES
var orderdPeople = from p in people
    orderby p.Name descending
    select new { p.Name, p.Age, p.Gender, p.Children };

// Order by multiple fields
var orderdPeople = from p in people
    orderby p.Age, p.Name descending
    select new { p.Name, p.Age, p.Gender, p.Children };

// Reverses the order
var orderdPeople = (from p in people
    orderby p.Name
    select new { p.Name, p.Age, p.Gender, p.Children }).Reverse ();


// **** PARTITIONING ****
// All partitioning functions should be done with Linq ext methods Take(), Skip(), TakeWhile() SkipWhile(); see Linq Ext cheet sheet here

// **** PROJECTION ****
// Select column
var allFemaleNames = from p in people
                    where p.Gender == Gender.Female
                    orderby p.Name descending
                    select p.Name;
// Select columns into anonymous type
var parentsNameAndAge = from p in people
    where p.Gender == Gender.Female
    select new { Name =  p.Name, Age = p.Age };

// Select element
var boysWithFemaleParents = from parent in people
    where parent.Gender == Gender.Female
    from children in parent.Children
    where children.Gender == Gender.Male All
    select children;

// **** QUANTIFIERS ****
// Any() and All() functions can be applied here

// Any exists
var isAnyPeople = (from p in people
                   where p.Gender == Gender.Unknown
                   select p).Any ();

// Any exists in group
var isAnyPeople = from p in people
                  where p.Children.Any (child => child.Gender == Gender.Unknown)
                  group p by p.Gender into genders
                  select new { Gender = genders.Key, People = genders};


// **** SETS ****
// Most set functions should be done with Linq ext methods Take(), Skip(), TakeWhile() SkipWhile(); see Linq Ext cheet sheet here
// inner join between person and gender description
var foo = from aPerson in people
    join aDes in genderDescriptions on aPerson.Gender equals aDes.Gender
select new { Name = aPerson.Name, Gender = aPerson.Gender, Desc = aDes.Descripion};