LINQ Core Operation: 

  • Filtering (Where): Chooses items from a sequence using a predicate—a condition.

var recs= records.Where(p => p.Age >= 25);
foreach (var rec in recs) {
    Console.WriteLine(rec .Name);
}

 

 

  • Projection (Select): Alters every sequence component into a new form.

var names = records.Select(p => p.Name);
foreach (var name in names){
    Console.WriteLine(name);
}

 

 

  • Sorts the components of a series in ascending or descending order using Ordering (OrderBy, OrderByDescending, ThenBy, ThenByDescending). Secondary sorting is done with ThenBy and ThenByDescending. 

// Ordering (OrderBy, OrderByDescending, ThenBy, ThenByDescending)
var sortedByAge = records.OrderBy(p => p.Age).ThenByDescending(p => p.Name);
foreach (var person in sortedByAge){
    Console.WriteLine($"{person.Name} ({person.Age})");
}

// Grouping (GroupBy) and then order by
var recsbyCity= records.GroupBy(p => p.City);
foreach (var group in recsbyCity) {   
    foreach (var rec in group)    {
        Console.WriteLine($"  - {rec .Name}");
    }
}

 

 

  • Grouping (GroupBy): Groups the components of a sequence according to a given key selector. Based on a related key, joining (Join, GroupJoin) merges components from two sequences. Join yields a flat outcome; GroupJoin yields a sequence of result groups. 

 // --- Joining (Join, GroupJoin)   ---  
var cities = new List<string>() { "Delhi", "Mumbai", "Bangalore" };
var recWithCityInfo = people.Join(
           cities,
           person => person.City,
           city => city,
           (person, city) => new { PersonName = person.Name, CityName = city };


foreach (var item in recWithCityInfo )   {
      Console.WriteLine($"{item.PersonName} lives in {item.CityName}");
}

 

--- Group Joining (GroupJoin) ---
var cityGroups = cities.GroupJoin(
           people,
           city => city,
           person => person.City,
           (city, cityPeople) => new { City = city, People = cityPeople }
       );


 foreach (var group in cityGroups)     {
           Console.WriteLine($"City: {group.City}");
 foreach (var person in group.People)       {
               Console.WriteLine($"  - {person.Name}");
  }
 if (!group.People.Any())         {
               Console.WriteLine("  - No residents");
 }
 


  • Aggregation (Count, Sum, Min, Max, Average, Aggregate): Runs calculations across a sequence of numbers. Aggregate runs a sequence of accumulator functions. 

// Aggregation (Count, Sum, Min, Max, Average, Aggregate)
Console.WriteLine($"Total people: {people.Count()}");

Console.WriteLine($"Sum of ages: {people.Sum(p => p.Age)}");

Console.WriteLine($"You ngest person's age: {people.Min(p => p.Age)}");

Console.WriteLine($"Oldest person's age: {people.Max(p => p.Age)}");

Console.WriteLine($"Average age: {people.Average(p => p.Age)}");

var allHobbies = people.Aggregate("", (current, p) => current + (current.Length > 0 ? ", " : "") + string.Join(", ", p.Hobbies));
Console.WriteLine($"All hobbies: {allHobbies}");

 

 

  • Quantifiers - All, Any, Contains: Return a boolean value showing whether the entries in a sequence satisfy particular criteria. 

Quantifiers (All, Any, Contains)

bool allAdults = people.All(p => p.Age >= 20);

Console.WriteLine($"Are all people adults? {allAdults}");

bool anyHobbies = people.Any(p => p.Hobbies.Contains("Coding"));
Console.WriteLine($"Does anyone like coding? {anyHobbies}");

bool containsAlice = people.Contains(people.FirstOrDefault(p => p.Name == "Alice"));
Console.WriteLine($"Does the list contain Alice? {containsAlice}");

 

 

  • Element Operators: First, FirstOrDefault, Last, LastOrDefault, Single, SingleOrDefault, ElementAt, ElementAtOrDefault Get a particular item from a series. The "OrDefault" variants give a default value should no corresponding element be found. Single and SingleOrDefault anticipate precisely one matching item. 


var firstPersonDelhi = people.First(p => p.City == "Delhi");
Console.WriteLine($"First person from Delhi: {firstPersonDelhi.Name}");


var lastPersonMumbai = people.LastOrDefault(p => p.City == "Mumbai");
Console.WriteLine($"Last person from Mumbai: {lastPersonMumbai?.Name}");


var singlePersonKolkata = people.SingleOrDefault(p => p.City == "Kolkata");
Console.WriteLine($"Single person from Kolkata: {singlePersonKolkata?.Name}");


var personAtIndex2 = people.ElementAtOrDefault(2);
Console.WriteLine($"Person at index 2: {personAtIndex2?.Name}");


  • Sets Operators (Distinct, Union, Intersect, Except) Execute set operations on sequences including deleting duplicates, merging sequences, identifying shared components, or locating items present in one sequence but absent in another. 

 

var citiesWithDuplicates = new List<string> { "Delhi", "Mumbai", "Delhi", "Kolkata", "Mumbai" };

var uniqueCities = citiesWithDuplicates.Distinct();
Console.WriteLine($"Unique cities: {string.Join(", ", uniqueCities)}");

var list1Hobbies = new List<string> { "Reading", "Hiking", "Coding" };
var list2Hobbies = new List<string> { "Coding", "Music", "Painting" };
var unionHobbies = list1Hobbies.Union(list2Hobbies);
Console.WriteLine($"Union of hobbies: {string.Join(", ", unionHobbies)}");

 

var intersectHobbies = list1Hobbies.Intersect(list2Hobbies);
Console.WriteLine($"Intersection of hobbies: {string.Join(", ", intersectHobbies)}");


var exceptHobbies = list1Hobbies.Except(list2Hobbies);
Console.WriteLine($"Hobbies in list1 but not in list2: {string.Join(", ", exceptHobbies)}");

 

 

 

  • Conversion Operators: Cast, OfType, ToArray, ToList, ToDictionary, ToLookup Transform a sequence into another collection kind. Type conversion and type filtering are done using Cast and OfType.

Conversion Operators (ToArray, ToList, ToDictionary, ToLookup, Cast, OfType)
 


string[] namesArray = people.Select(p => p.Name).ToArray();
Console.WriteLine($"Names as array: {string.Join(", ", namesArray)}");


Dictionary<int, string> peopleDictionary = people.ToDictionary(p => p.Id, p => p.Name);
Console.WriteLine($"People as dictionary (Id -> Name): {string.Join(", ", peopleDictionary)}");


var peopleLookup = people.ToLookup(p => p.City);
foreach (var group in peopleLookup){
    Console.WriteLine($"  {group.Key}: {string.Join(", ", group)}");
}

 

List<object> mixedList = new List<object> { 1, "two", 3.0, new Person { Id = 6, Name = "Frank" } };
var intList = mixedList.OfType<int>();
Console.WriteLine($"Integers from mixed list: {string.Join(", ", intList)}");


var personList = mixedList.OfType<Person>();
Console.WriteLine($"People from mixed list: {string.Join(", ", personList.Select(p => p.Name))}");

 

// Deferred Execution Example
var delhiResidents = people.Where(p => p.City == "Delhi");
people.Add(new Person { Id = 7, Name = "Grace", Age = 22, City = "Delhi", 

Hobbies = new List<string>() }); // Added after query definition
Console.WriteLine("Delhi residents (after adding Grace):");
foreach (var resident in delhiResidents) {
    Console.WriteLine(resident.Name); // Grace will be included
}

// Immediate Execution (using ToList)
var mumbaiResidentsNow = people.Where(p => p.City == "Mumbai").ToList(); // Executed immediately


people.Add(new Person { Id = 8, Name = "Heidi", Age = 27, 
City = "Mumbai", 
Hobbies = new List<string>() }); // Added after immediate execution


Console.WriteLine("Mumbai residents (after adding Heidi):");
foreach (var resident in mumbaiResidentsNow){
    Console.WriteLine(resident.Name); // Heidi will NOT be included
}

 


Filter n Projection

using System;
using System.Collections.Generic;
using System.Linq;

namespace PersonAgeFilter
{
   // Define the Person class
   public class Person
   {
       public string Name { get; set; }
       public int Age { get; set; }
   }

   class Program
   {
       static void Main(string[] args)
       {
           // Create a list of Person objects
           List<Person> personList = new List<Person>();
           
           personList.Add( new Person{Name="Alice", Age=32});
           personList.Add( new Person{Name="Charlie", Age=40});
           personList.Add( new Person{Name="David", Age=29});
           personList.Add( new Person{Name="Eve", Age=35});
           personList.Add( new Person{Name="Alice", Age=15});
           

           // Use LINQ to filter persons with age >= 30 and select their names
           List<string> olderPeopleNames = personList.Where(person => person.Age >= 30)
                                                .Select(person => person.Name)
                                                .ToList();

           // Print the names of the older people
           Console.WriteLine("Persons with age >= 30:");
           foreach (string name in olderPeopleNames)
           {
               Console.WriteLine(name);
           }

           //Alternative: Print Person Objects
           List<Person> olderPeople = personList.Where(person => person.Age >= 30).ToList();
           Console.WriteLine("\nPersons with age >= 30 (Objects):");
           foreach (Person person in olderPeople)
           {
               Console.WriteLine(person.Name); // Uses the ToString() override in Person class
           }
       }
   }
}
 

 


Related Question